How-to and systemd scripts for automated backups with restic
Updated to include excludes, and instructions for installing as non-root
README is now aware that it lives in the repo.


browse log



#Backups with restic

Backups with restic are pretty easy, but it may save someone some time if I document my configuration.

This outlines how to set up backups to B2 (Backblaze) using restic. It isolates configuration data and credentials, and uses systemd for the scheduling. I'm not going to justify any of the decisions, except to say that Backblaze is a great service, and is both extremely cost effective and easy to use with restic, as restic has built-in support for it.

At the end of this, you'll have encrypted, automated backups in the cloud.


These instructions have you cat-ing content into files; however, you can also check out this repository, edit the files in it, and copy them to the destinations listed in the instructions. It's probably easier that way.


  • restic
  • systemd
  • A Backblaze account


This is based on directory structures in Debian, which is what I have to use because my VPS provider doesn't support Arch. However, while untested, this should be the same for other systems with the same base packages. When you're done, the relevant file structure will look like this:

  • /etc/backup
  • /etc/backup/environment
  • /etc/backup/paths
  • /etc/backup/excludes
  • /lib/systemd/system/backup.service
  • /lib/systemd/system/backup.timer
  • /lib/systemd/system/backup-prune.service
  • /lib/systemd/system/backup-prune.timer

#Steps (as user)

If you want to back up your home directory as a user, you don't need to install all of this as root. The simple way is:

# Get this repository; say it lives in $PWD/restic-backup/
mkdir .config/restic
cp restic-backup/{environment,paths,excludes} .config/restic/
mkdir -p .config/systemd/user
cp restic-backup/backup*{service,timer} .config/systemd/user/
# Edit environment, paths, and excludes appropriately
systemctl enable backup.timer
systemctl enable backup-prune.timer

#Steps (as root)

#1. Set up your Backblaze account

You'll create an account, a bucket, and then an access key for the bucket.

Visit Backblaze and create an account. Create a bucket for your backups a key for the bucket; I create a unique key for every server, to limit damage if one server is compromized. For the same reason, I also limit bucket access for each key to exactly one bucket. If you're using multiple buckets on one machine, re-using the key would make sense.

Copy the account ID and access key from the key you create, as well as the name of the bucket. If you have multiple servers, each of these attributes will be unique as B2 assigns a unique ID and key for each bucket.

#2. The configuration files

sudo mkdir /var/cache/restic
sudo mkdir /etc/backup
sudo chmod 700 /etc/backup

Make sure that the /etc/backup directory is secured, as it will contain credentials. In my examples, you'll want to replace the IDs and keys with the ones from your account.

cat <<EOL | tee environment
RESTIC_PASSWORD="Really secure password goes here."

The first two variables come directly from Backblaze. The third needs to start with b2 and end with restic, and replace the middle part with the name you gave the bucket. Files is the name of a file that contains the paths of the files and directory you want to back up; it's one-line per file or directory, and use full paths. KEEP_DAYS tells restic how many backups to keep; this is a matter of choice, and the restic-forget man page explains it best.

cat <<EOL | tee paths

Add your other backup paths or files to the paths file; you don't have to back up the files in this list -- it's just an example.

#3. Scheduling

The backup service itself both backs up and then marks entries for future pruning.

sudo cat <<EOL | tee /lib/systemd/system/backup.service
Description=Restic-based backup

ExecStart=/usr/local/bin/restic backup --files-from ${FILES} --cache-dir ${RESTIC_CACHE_DIR}


Next is the timer. Set the period to whatever you want -- I'm doing twice a week below. The man page that explains the OnCalendar time format is systemd.time (e.g., man systemd.time).

sudo cat <<EOL | tee /lib/systemd/system/backup.timer
Description=Restic-based backup timer



Pruning makes a lot of API calls to B2, so to control costs I run this less frequently. It's a trade-off, because pruning reduces the amount of storage in the buckets, which can also save money. For my use case, it's reasonable to run it once a month.

If you have chosen to prune on a different, less frequent, schedule, then add the following services:

sudo cat <<EOL | tee /lib/systemd/system/backup-prune.service
Description=Restic-based pruning job

ExecStartPre=/usr/local/bin/restic forget --keep-daily ${KEEP_DAILY} --keep-monthly ${KEEP_MONTHLY} --keep-yearly ${KEEP_YEARLY} --cache-dir ${RESTIC_CACHE_DIR}
ExecStart=/usr/local/bin/restic prune --cache-dir ${RESTIC_CACHE_DIR}

sudo cat <<EOL | tee /lib/systemd/system/backup-prune.timer
Description=Restic-based backup pruning job timer

OnCalendar=Sunday 01:00:00


Once these are all created, tell systemd about them:

sudo systemd daemon-reload
sudo systemctl enable backup.service
sudo systemctl enable backup.timer
sudo systemctl enable backup-prune.service
sudo systemctl enable backup-prune.timer
sudo systemctl start backup.timer
sudo systemctl start backup-prune.timer

You can see the timers with list-timers:

sudo systemctl list-timers


Most of the work here is in having everything cleanly separated, with the configuration in separate files, hiding credentials, and creating the service descriptions. Setting up Backblaze and running restic are anticlimactically trivial.

I hope that this can save someone a little time.