Why a dedicated backup tool?
Backups processes come in all shapes and sizes, from simple bash scripts to cloning entire disks or entire tools managing the lifecycle. There is nothing wrong with either of these approaches, but using a fully integrated tool like restic combines the reliability and features of an enterprise grade backup system with the simplicity of just a few terminal commands, striking a nice balance for administrators that are looking for a robust backup tool that "just works" - without diving deep into their implementation.
In the case of restic, it provides several features out of the box. It runs natively on linux, windows and mac and supports many different providers to store backups, from local directories to sftp servers or even S3-compatible object storage. I fully encrypts backups by default and uses deduplication to prevent storing files unnecessarily, effectively turning all backups into incremental backups. Stored data is compressed at configurable levels and integrity checks are available out of the box to detect data corruption. Finally, backups can be mounted over the network to easily inspect their contents, and restoring a snapshot is also just a single command away.
restic is available in most default software repositories, for example on debian-like systems:
sudo apt install restic
Since restic works without requiring a server component, this single command is all you need.
Creating a repository
Before any backups can be made, restic needs to initialize a repository (aka storage location). This can be any number of different things, for example a local directory, remote sftp server or S3 object storage bucket.
You can supply the repository identifier from the command line using the -r
/ --repo
flag and be prompted for an encryption password:
restic init --repo /path/to/repo
# or
restic -r sftp:user@host:/path/to/repo init
or load from the environment variables RESTIC_REPOSITORY
and RESTIC_PASSWORD
:
export RESTIC_REPOSITORY=/path/to/repo
export RESTIC_PASSWORD=supersecret
restic init
If you prefer using S3 storage, exporting your credentials with the default AWS environment variables is enough:
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/bucket-name/folder
export RESTIC_PASSWORD=supersecret
restic init
Make sure to prepend the type of remote storage in front of the repository url, like the sftp:
or s3:
protocol prefixes in the examples above.
Be careful to remember your repository password or store it in a password manager! Encryption protects unauthorized eyes from accessing your backup data - including you if you lose the password!
Note: all further sections assume you have exposed the RESTIC_REPOSITORY
environment variables or manually add your repository through -r
/ --repo
to the commands.
Making backups
Once the repository is set up, making a backup is extremely easy:
restic backup /home/user/Documents
You can also include multiple directories in a backup:
restic backup /etc /home/user/Pictures /var/log
You can exclude single files with --exclude-file
or entire directories with --exclude
:
restic backup /home/user --exclude /home/user/Downloads --exclude-file /home/users/.bash_history
If you want restic to ignore mount points within the target backup directory, you can supply --one-filesystem
:
restic backup /home/user --one-filesystem
Suppose an external drive were mounted at /home/user/mnt
, that directory would not be included in the backup.
Finally, using --tag
allows you to label backups so you can identify them easier later. A daily background backup command might look like this:
restic backup / --exclude /sys --exclude /proc --exclude /dev --one-file-system --tag daily
This backs up all disk contents, omitting other other mounted drives and system-specific directories. Backups are tagged "daily" so you can later distinguish them from manual backup snapshots.
This backup command needs to be scheduled by an external job manager like cron or systemd timers, since restic does not provide a daemon out of the box.
Inspecting backups
You can list all the snapshots (aka backups) in a repository with
restic snapshots
The output will list all known snapshots:
repository 46a48ae4 opened (repository version 2) successfully, password is correct
ID Time Host Tags Paths
---------------------------------------------------------------
46a4c248 2025-04-27 17:09:29 bookworm daily /var/log
34db447d 2025-04-27 17:09:37 bookworm daily /var/log
d1d7ca1c 2025-04-27 17:09:42 bookworm manual /var/log
---------------------------------------------------------------
3 snapshots
This is also where you can see the tag coming in handy, clearly separating the daily backups from the manual one in the list. To get a list of files inside a snapshot, note it's ID (first column in the list above) and run restic ls
:
restic ls 46a4c248
The command will display all contained files, one per line:
snapshot 46a4c248 of [/var/log] filtered by [] at 2025-04-27 17:09:29.91681622 +0000 UTC):
/var
/var/log
/var/log/README
/var/log/apt
# --- snip ---
You can include permissions, filesize and more by passing the --long flag tot he command:
restic ls 46a4c248 --long
The output becomes significantly more detailed:
snapshot 46a4c248 of [/var/log] filtered by [] at 2025-04-27 17:09:29.91681622 +0000 UTC):
drwxr-xr-x 0 0 0 2024-09-05 04:33:28 /var
drwxr-xr-x 0 0 0 2025-04-27 17:01:29 /var/log
Lrwxrwxrwx 0 0 0 2024-09-05 04:33:48 /var/log/README -> ../../usr/share/doc/systemd/README.logs
drwxr-xr-x 0 0 0 2025-04-27 17:05:50 /var/log/apt
For even more visibility, you can mount an entire snapshot to a directory:
restic mount /mnt
This mounts the entire repository, including all snapshots, at /mnt
. You can now manually access and filter the exact backup contents with common utilities like find. The mount command will hang until you stop it by pressing ctrl
+c
, which automatically unmounts the repository.
Note that mounted repositories are read-only, you cannot use this feature to remove backup contents. This also means you are safe from accidentally corrupting/damaging snapshots by mounting them.
Restoring a backup
Should the need arise to recover from a desaster scenario, restic maintains it's batteries-included approach. Find the ID of your desired backup and run
restic restore snapshot-ID --target /restore/target/path
If desired, you can also decide to restore only specific directories or files:
restic restore snapshot-ID --target /restore/target --include /home/user/Documents/file.txt
If you are not sure how long ago a file was deleted or damaged, you may be able to quickly filter through your most recent backups by comparing their changes, to find one that still contains the desired file:
restic diff 46a4c248 6c0f0765
a list of modified files and summary if changes is printed to the terminal:
comparing snapshot 46a4c248 to 6c0f0765:
M /var/log/auth.log
M /var/log/cron.log
M /var/log/journal/a57af1475f474a5c9af886ce5a0c56a0/system.journal
+ /var/log/new_file!
M /var/log/syslog
Files: 1 new, 0 removed, 4 changed
Dirs: 0 new, 0 removed
Others: 0 new, 0 removed
Data Blobs: 12 new, 11 removed
Tree Blobs: 5 new, 5 removed
Added: 4.094 MiB
Removed: 4.092 MiB
If this doesn't help or you have too many snapshots, you may need to mount the repository and search with system utilities instead.
Backup retention and maintenance
The built-in retention features allows operators to define how many old backups should be kept, and which can be deleted. This works by running restic forget
with a list of rules which backups to keep; all others are considered removable. You can test your retention policy safely by using the --dry-run
flag:
restic forget --dry-run --keep-within 24h --keep-daily 7 --keep-monthly 12
This policy would keep all backups from the last 24h, one per day for a week and one per month for a year. Removing the --dry-run flag would apply the retention policy, removing references to all snapshots not kept by the defined rules.
Be aware that forgetting snapshots only removes references to them and doesn't delete their data from storage. To do that you need to prune the repository:
restic prune
You can combine forget and prune in a single command as well:
restic forget --keep-daily 30 --prune
Now only the latest backup per day is kept for the last 30 days, all others are forgotten and permanently deleted from the repository.
Integrity checking
Ensuring data is still valid and safe to use is important for any backup solution; having corrupted backups is like having no backups at all. Restic uses internal checksums to ensure data corruption can be detected:
restic check
If any data corruption is found, the command will alert you to it. Data corruption cannot be fixed by restic itself, so it is important to keep safety copies of your backup repository on a separate disk (or better, a different device/service entirely).
If only the restic metadata is damaged, you may be able to fix it by regenerating it:
restic rebuild-index
This only works for limited scenarios, and does not replace a proper safety copy strategy.