Backups with Restic

Posted on 2022-11-09 in misc • 4 min read

Introduction

For many years, I had paid for a CrashPlan home user plan and backed up all my systems with that. It was pretty simple, had a basic "set-it-and-forget-it" kind of thing going for it. 5 years ago, they ended the Home user version and were only offering a small business edition, which was way more expensive, and I gave up on CrashPlan. At that point, I had moved to using Duplicity, and then later started using Duply as a front-end to managage different backup sets. It worked fine, and I was happy with it for nearly five years.

I often would see references to Borg and Restic as "modern" backup options, but was perfectly happy with my Duplicity backup. It was working, so I didn't see any need to change it.

I had a scare on my media drive and started to verify my backup practices and found that I hadn't backed that volume up since 2019. There aren't that many changes on there over that time, so I wouldn't have lost a whole lot if I had to recover, but I decided that I wanted to get a backup of that before I did any more weird stuff on the drive. Given the amount of data, and the time it was going to take, I thought it might be worthwhile to look at other options for backup, and ultimately I decided to give restic a try. And then I fell in love with restic, and converted all my machines' backups to restic.

What's so great about restic

Duplicity effectively uses PGP to encrypt things, tar to create the storage packages that are sent to the storage provider, and rsync to copy them there. It's not exactly that straightforward, but effectively, that's what is happening.

Restic, on the other hand, uses something a little more like git (again, not technically git, but the thought processes behind it are similar). Instead of creating a tar file and piecing everything together, it hashes the file and uploads that to the repository. Any other copies of that file are simply referenced to that. So if you have multiple machines backing up to the same repository, and they are all the same OS, all those OS files that are the same across X number of machines is only actually stored once, then in the index there is a reference to that object. It makes much better use of storage, and greatly speeds up the backups (after the initial one of course).

There are quite a few things that are actually pretty great about Restic, but the storage bit is foundational, and ultimately makes everything else so much better.

Installation

Installation on Fedora was as simple as

yum -y install restic

I'm using Google Drive as my storage back-end, and restic doesn't natively support that, but it does through rclone, so I also had to

yum -y install rclone

Setup

Setup rclone

After installing the required components, the first thing is to setup rclone. This is basically as simple as running rclone config and following the prompts for google drive.

Note

For google drive, you have to set up an app with the google drive API access. All of those details are covered in rclone's docs.

Setup restic

Once you have a google drive remote set up in rclone, now you can get started with the restic configuration by first initializing it

restic -r rclone:google:yourpath init

Assuming that works then it's good to go for a backup of something like:

restic -r rclone:google:yourpath /home

My Backup Scripts

I started with the script on this page, corrected the errors in it, and made a few modificionats to get to this:

#!/usr/bin/env bash

# Exit on failure or pipefail
set -e -o pipefail

#Set this to any location you like
BACKUP_PATHS="/"
BACKUP_EXCLUDES="/etc/restic/exclude"


BACKUP_TAG=$(hostname -s)

# How many backups to keep.
RETENTION_DAYS=7
RETENTION_WEEKS=4
RETENTION_MONTHS=3
RETENTION_YEARS=1

source /etc/restic/env

# Remove locks in case other stale processes kept them in
restic unlock &
wait $!

#Do the backup

restic backup \
       --verbose \
       --tag $BACKUP_TAG \
       --exclude-file $BACKUP_EXCLUDES \
       $BACKUP_PATHS &

wait $!

# Remove old Backups

restic forget \
       --verbose \
       --tag $BACKUP_TAG \
       --prune \
       --keep-daily $RETENTION_DAYS \
       --keep-weekly $RETENTION_WEEKS \
       --keep-monthly $RETENTION_MONTHS \
       --keep-yearly $RETENTION_YEARS &
wait $!

# Check if everything is fine
restic check &
wait $!

 echo "Backup done!"

For that to work, I also have an env file that is sourced in there that has the following things set:

export RESTIC_PASSWORD=<my repo password>
export RESTIC_REPOSITORY=rclone:google:$(hostname -s)
export RESTIC_CACHE_DIR=/archive/restic

I'm still very early in scripting the backups, and I want to get some notifications to my matrix server, especially when things don't work. But this is working for me currently.