Updated to include excludes, and instructions for installing as non-root
README is now aware that it lives in the repo.
Initial commit
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.
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:
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
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.
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
B2_ACCOUNT_ID=YOUR_B2_BUCKET_KEY_ID
B2_ACCOUNT_KEY=YOUR_B2_BUCKET_KEY_SECRET
RESTIC_REPOSITORY=b2:name-of-your-backup:restic
RESTIC_PASSWORD="Really secure password goes here."
RESTIC_CACHE_DIR=/var/cache/restic
FILES=/etc/backup/paths
KEEP_DAYS=28
EOL
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
/etc/backup
/lib/systemd/system/backup.service
/lib/systemd/system/backup.timer
/lib/systemd/system/backup-prune.service
/lib/systemd/system/backup-prune.timer
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.
The backup service itself both backs up and then marks entries for future pruning.
sudo cat <<EOL | tee /lib/systemd/system/backup.service
[Unit]
Description=Restic-based backup
After=network.target
[Service]
EnvironmentFile=/etc/backup/environment
Type=simple
ExecStart=/usr/local/bin/restic backup --files-from ${FILES} --cache-dir ${RESTIC_CACHE_DIR}
[Install]
WantedBy=multi-user.timer
EOL
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
[Unit]
Description=Restic-based backup timer
After=network.target
[Timer]
OnCalendar=04:00:00
Persistent=True
[Install]
WantedBy=timers.target
EOL
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
[Unit]
Description=Restic-based pruning job
Requires=network.target
After=network.target
[Service]
EnvironmentFile=/etc/backup/environment
Type=simple
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}
[Install]
WantedBy=multi-user.timer
EOL
sudo cat <<EOL | tee /lib/systemd/system/backup-prune.timer
[Unit]
Description=Restic-based backup pruning job timer
Requires=network.target
After=network.target
[Timer]
OnCalendar=Sunday 01:00:00
Persistent=True
[Install]
WantedBy=timers.target
EOL
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.