How to Make Encrypted, Deduplicated Backups with restic

restic: encrypted, deduplicated backups — Snapshots you can browse. Local or cloud. Same commands.

The rsync-and-tar approach (tutorial 23) works, but it has limits: every dated archive is a full copy, nothing is encrypted, and restoring one file from last Tuesday means unpacking the whole archive. restic fixes all three. It takes snapshots — each one looks like a full backup, but only the blocks that changed are stored — encrypts everything, and can write to a local folder, an SFTP server, Backblaze B2 or any S3 bucket with the same commands.

Quick reference

TaskCommand
Installsudo apt install restic -y && sudo restic self-update
Create a repositoryrestic init -r /mnt/backup/restic
Back uprestic backup /home /etc /var/www
List snapshotsrestic snapshots
Restorerestic restore latest --target ~/restore --include /etc/nginx
Thin out old snapshotsrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
Check integrityrestic check

1. Install

sudo apt install restic -y
sudo restic self-update

2. Create a repository

A repository is just a folder (or bucket) restic manages. Locally:

sudo restic init -r /mnt/backup/restic

It asks for a password. Write it down somewhere off the server — the repository is unreadable without it.

For Backblaze B2 instead:

export B2_ACCOUNT_ID=keyid B2_ACCOUNT_KEY=appkey
restic init -r b2:bucket-name:server

3. Stop typing the password and path

sudo nano /root/.restic.env

export RESTIC_REPOSITORY=/mnt/backup/restic
export RESTIC_PASSWORD=your-repo-password

sudo chmod 600 /root/.restic.env, then source /root/.restic.env before any restic command (the script below does this).

4. First backup

sudo bash -c 'source /root/.restic.env && restic backup /home /etc /var/www /home/john/docker --exclude /home/*/.cache'

The first run copies everything. Every run after that takes seconds to minutes, because only changed blocks are sent — even inside large files.

Databases still need dumping first (mysqldump to a file that restic then backs up).

5. Look at what you've got

sudo restic snapshots
sudo restic ls latest /etc/nginx
sudo restic diff <id1> <id2>

Or mount the whole history and browse it like folders:

sudo mkdir -p /mnt/restic && sudo restic mount /mnt/restic

/mnt/restic/snapshots/2026-10-08T02:00:01/etc/... — every snapshot, every file, read-only. Ctrl + C unmounts.

6. Restore

One folder from the latest snapshot:

sudo restic restore latest --target /tmp/restore --include /etc/nginx

Everything from a specific snapshot: sudo restic restore 3a1b2c3d --target /.

7. Keep it tidy

sudo restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

That keeps a snapshot for each of the last 7 days, 4 weeks and 12 months, and --prune reclaims the space.

8. The nightly script

sudo nano /usr/local/bin/restic-backup.sh

#!/bin/bash
set -e
source /root/.restic.env
mysqldump --all-databases | gzip > /var/backups/db.sql.gz
restic backup /home /etc /var/www /var/backups /home/john/docker --exclude-caches --quiet
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune --quiet
echo "restic ok $(date +%F)"

sudo chmod +x /usr/local/bin/restic-backup.sh
sudo crontab -e

0 2 * * * /usr/local/bin/restic-backup.sh >> /var/log/restic.log 2>&1

Run sudo restic check monthly.

Two repositories

The best setup is a local repository for fast restores and a B2 one for disaster. Either run the backup twice with different RESTIC_REPOSITORY values, or rclone the local repository to the cloud (tutorial 54) — restic repositories copy perfectly.

Troubleshooting

"repository is already locked". A previous run was interrupted. restic unlock.

"wrong password or no key found". The password in .restic.env doesn't match. Repositories can have several keys: restic key add.

Backup is slow on the first run. Expected; it reads everything once. Later runs are fast.

Disk filling despite forget. You forgot --prune, which actually deletes the data.

Wrapping up

Init a repository, back up a list of folders, forget-and-prune on a policy, cron it. Encrypted, deduplicated, browsable snapshots to anywhere, with the same four commands whether the target is a USB drive or a bucket on the other side of the world.

Call us