DevLogTechnical writing
Tutorials

Back up a Linux server with restic

September 20, 2026

A backup you only half trust isn't a backup. The way to build trust is to make the restore path boring and repeatable well before you need it. restic is a modern choice for this: it stores encrypted, deduplicated snapshots, so repeated backups of nearly-unchanged data are small, and each snapshot is a complete point-in-time view you can restore from. Like git, it's a collection of subcommands around one repository.

On Ubuntu or Debian, install it with:

sudo apt install restic

This guide backs up a folder, checks the snapshots, restores a file, then automates it with cron.

Initialize a repository

A repository is where restic stores everything. Point it at an empty directory — local or remote — and initialize:

restic init -r /srv/restic-repo

You'll be prompted to set a password twice. The repository is encrypted with that password, so losing it means your data is irrecoverably lost — write it somewhere safe before relying on this repo.

Take your first snapshot

restic -r /srv/restic-repo backup ~/work

restic scans the files, stores them encrypted, and prints a summary ending with the snapshot ID it saved. Run it again after a change and only the changed chunks are written; that's the deduplication doing its job.

Look at what you have

restic -r /srv/restic-repo snapshots

This lists every snapshot with its ID and timestamp.

Restore a file

restic restore extracts a snapshot to a target directory without touching the originals:

restic -r /srv/restic-repo restore latest --target /tmp/restore

latest is a convenience: it always resolves to the most recent snapshot. Restoring just one file is a targeted --include:

restic -r /srv/restic-repo restore latest --target /tmp/restore --include /home/user/work/important.txt

Restoring to a scratch directory first is a good habit — if an in-place restore is interrupted mid-write you can end up with a partially-restored tree.

Prune old backups

Snapshots accumulate. forget removes snapshots from the repository index, and prune actually deletes the data they referenced, in a retention pattern you choose:

restic -r /srv/restic-repo forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

This keeps a week of dailies, plus four weekly and twelve monthly snapshots, then removes the data no longer referenced by anything. The --prune flag is what actually reclaims space — without it, forget only hides the snapshots.

Automate it with cron

Automation is where restic shines, and it does this cleanly with environment variables and a password file. Store the repository location and the password in a script. First write the password to a file only root can read:

echo 'your-long-password' > /etc/restic-pw && chmod 600 /etc/restic-pw

Then a backup script, /usr/local/bin/restic-backup.sh:

#!/usr/bin/env bash
set -e
export RESTIC_REPOSITORY="/srv/restic-repo"
export RESTIC_PASSWORD_FILE="/etc/restic-pw"
restic backup /etc /home --exclude /home/*/.cache
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

Make it executable and run it once by hand — never cron a script you haven't tested manually. Then add a nightly job with crontab -e:

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

Now the backups happen whether or not you remember, with the empty check being restic snapshots — run that monthly, so a silently-failing job can't hide.

What's next

Keep a copy of the repository somewhere other than the same disk as your data; restic speaks many remote backends (SFTP, S3, and others) by changing the repository URL scheme. Before going production, run restic check to verify the repository is intact, and restore one snapshot end-to-end so the first time you exercise it isn't during a crisis.

← More Tutorials