Boring, reliable backups with restic and a systemd timer
For years my backup strategy was "copy things to a USB drive when I remember". This post describes what replaced it: restic, an S3-compatible bucket and two small systemd units.
Why restic
It is a single static binary, it encrypts everything client-side, deduplicates well and supports a dozen storage backends. Most importantly, restoring a single file is easy — which means I actually test it.
The service unit
[Unit]
Description=restic backup
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/bin/restic backup /home /etc --exclude-caches
ExecStartPost=/usr/bin/restic forget \
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
The environment file holds the repository URL, the credentials and the repository password. It is owned by root with mode 0600, which is the least I can do.
The timer
[Unit] Description=nightly restic backup [Timer] OnCalendar=*-*-* 03:30 RandomizedDelaySec=15m Persistent=true [Install] WantedBy=timers.target
Persistent=true matters on a machine that is not always on: if it was asleep at 03:30, the job runs at the next boot instead of being skipped silently.
Testing restores
A backup you have never restored is a hope, not a backup. Once a week another job picks a random file from the latest snapshot, restores it into a temporary directory and compares its checksum with the original. If they differ, or if the snapshot is older than two days, I get an email.
What I would do differently
I should have set up the monitoring first. For about three months the timer was failing because of an expired token, and I only noticed when I went looking for a deleted file. Now the absence of a fresh snapshot is itself an alert.
That's the whole setup. Nothing clever — which is exactly the point.