My small home server had “backups” in the sense that I copied things to an external disk when I remembered. I finally set up something automatic with restic.
Why restic: encrypted by default, deduplicated, a single static binary, and it supports local disks, SFTP, and S3-compatible storage with the same commands.
Repository
sudo apt install restic
sudo mkdir -p /etc/restic
sudo sh -c 'openssl rand -base64 32 > /etc/restic/password'
sudo chmod 600 /etc/restic/password
/etc/restic/env:
RESTIC_REPOSITORY=/mnt/backup/restic
RESTIC_PASSWORD_FILE=/etc/restic/password
sudo env $(cat /etc/restic/env) restic init
Copy the password somewhere that isn’t this machine. Without it the repository is just random bytes.
The backup job
/etc/systemd/system/restic-backup.service:
[Unit]
Description=restic backup
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/bin/restic backup --exclude-caches /etc /home /var/lib/docker/volumes
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
/etc/systemd/system/restic-backup.timer:
[Unit]
Description=nightly restic backup
[Timer]
OnCalendar=*-*-* 03:30
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
Persistent=true means a missed run (machine was off) happens at next boot.
Checking it
Once a week I let restic verify a random slice of the actual data, not just the metadata:
restic check --read-data-subset=5%
Test the restore
A backup you’ve never restored is a hope, not a backup. I restored /etc to a temp directory and
diffed it:
restic restore latest --target /tmp/restore-test --include /etc
diff -r /etc /tmp/restore-test/etc | head
Next step is a second copy off-site. Since restic speaks S3, that’s mostly a second repository and a
restic copy in the same timer.