Scheduled backups with systemd and restic
Oct 18, 2022 20:00 · 304 words · 2 minutes read
For many years I used my custom scripts to backup data from my personal mail server. It was a simple (dummy) script to compress files into an archive and upload this archive to my storage server using sftp. It worked, but it was not an efficient way to keep backups - every run stored everything again.
So I moved to restic, driven by a systemd timer. Here are the pieces.
/etc/restic/mail.conf
RESTIC_REPOSITORY=s3:https://DEMO.melnyk.org/backups/mails
RESTIC_PASSWORD=DEMOPASSWORD
AWS_SECRET_ACCESS_KEY=DEMOKEY
AWS_ACCESS_KEY_ID=DEMOKEYID
/etc/restic/mail.files
/var/data
/etc/systemd/system/restic-backup@.timer
[Unit]
Description=Schedule Restic Backup of %I at 2:00 AM
[Timer]
OnCalendar=*-*-* 2:00:00
[Install]
WantedBy=timers.target
/etc/systemd/system/restic-backup@.service
[Unit]
Description=Restic Backup of %I
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/%i.conf
ExecStart=/usr/bin/restic backup --files-from /etc/restic/%i.files
ExecStart=/usr/bin/restic forget --prune --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75
Both the timer and the service are templates, so %i is whatever comes after the @. Starting restic-backup@mail picks up /etc/restic/mail.conf and /etc/restic/mail.files, and the same pair of units can back up my other machines just by adding another config. The conf file keeps the repository password, so do not forget chmod 600 /etc/restic/mail.conf.
Also, we have to enable the timer to backup mail server files:
systemctl enable --now restic-backup@mail.timer
The second ExecStart line is the retention policy - without it the repository grows forever. I keep the last 7 daily snapshots, 5 weekly, 12 monthly and 75 yearly ones. Note the counts overlap: a snapshot that is both the last of the week and the last of the month is only kept once, so the real number is a bit lower. --prune is the part that actually frees the space in the repository, and it is why the nightly run is not instant.
The retention part can be run by hand too - add --prune to it if you want the space back right away:
restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75