How to create a backup chain

Let’s create a simple backup chain.

We’re going to use duplicity to upload everything in ~/backup/ to Backblaze B2 storage - a cost-effective solution which will be encrypted at rest, with 90-day rolling history.

Set up duplicity and B2

Backblaze have a great tutorial for setting up a B2 bucket and installing duplicity, but it’s a bit out of date. The short uv-friendly version:

sudo apt install \
    intltool \
    lftp \
    librsync-dev \
    libffi-dev \
    libssl-dev \
    openssl \
    par2 \
    rclone \
    rsync \
    rdiff \
    tzdata

Now lets create our local backup directory:

mkdir -p ~/backup

The duplicity commands to backup everything in ~/backup/ to B2 with a 90 day history will be:

export B2_URL="b2://[keyID]:[application key]@[B2 bucket name]"
uvx duplicity remove-older-than 90D -v9 --force $B2_URL
uvx duplicity --full-if-older-than 30D --copy-links ~/backup/ $B2_URL

You can download a fleshed out version of this from the runchain repo. Customise it then install it as 90-dup.sh, so it will run at the end of the backup chain:

wget https://raw.githubusercontent.com/radiac/runchain/refs/heads/main/samples/backup-dup.sh
# Update the secrets in backup-dup.sh
uvx runchain add backup backup-dup.sh 90-dup.sh

We can test the backup with:

uvx runchain run backup

Lastly, let’s schedule the chain to run at 2am every day:

uvx runchain cron backup "0 2 * * *"

Now everything in your ~/backup directory will be backed up to B2 at 2am.

Back up a file or directory

Because we have --copy-links, to back up a file or a directory, you can just symlink it in:

ln -s ~/uploads ~/backup/uploads

Back up something more complicated

Let’s see how we’d back up a PostgreSQL database running in a container.

Lets create dump-postgres.sh:

#!/bin/bash
set -e
docker exec postgres-container pg_dumpall > ~/backup/postgres_dump.sql

You can download a version of this with more options from the repo - customise it then install it as 50-postgres.sh, so it will run before 90-dup.sh:

wget https://raw.githubusercontent.com/radiac/runchain/refs/heads/main/samples/backup-postgres.sh
# Update the secrets in backup-postgres.sh
uvx runchain add backup backup-postgres.sh 50-postgres.sh

If you need to backup multiple databases, you can have multiple copies of this with different names.