Knowledgebase › Restic with Backblaze B2 — the cheap-and-cheerful off-host backup pairing

Restic with Backblaze B2 — the cheap-and-cheerful off-host backup pairing

Restic + Backblaze B2 is the lowest-friction credible off-host backup pairing for a single VPS. Encryption is built in, deduplication is automatic, B2 storage is cheap, and the restore story is solid. This article walks the full setup.

Why this combination

  • Restic: open-source, encrypted by default, deduplicating, single static binary.
  • Backblaze B2: S3-compatible object storage, cents per GB, cheap egress.
  • Both have been stable for years and have wide community adoption.

You can pair Restic with anything S3-compatible (Wasabi, R2, AWS S3, even MinIO if you have a second server). B2 is the cheapest mainstream option for small-volume backups.

Install restic

# Debian/Ubuntu
apt install restic

# AlmaLinux/Rocky
dnf install restic

# Or grab the latest binary directly
wget https://github.com/restic/restic/releases/latest/download/restic_VERSION_linux_amd64.bz2
bunzip2 restic_VERSION_linux_amd64.bz2
mv restic_VERSION_linux_amd64 /usr/local/bin/restic
chmod +x /usr/local/bin/restic

Set up B2

  1. Sign up at backblaze.com/b2.
  2. Create an application key with read+write+list permissions limited to a specific bucket.
  3. Create the bucket. Name it something specific to this VPS (e.g., backup-pbx-prod-2026). Private access only.
  4. Note the keyID and applicationKey. The bucket name and bucket ID also.

Configure restic

Create a credentials file at /etc/restic/env:

# Restic repository pointer
export RESTIC_REPOSITORY="b2:<bucket-name>:/"
# Restic encryption password — generate randomly, store
# somewhere off-host too (you cannot recover backups without it)
export RESTIC_PASSWORD="<long-random-password>"
# B2 credentials
export B2_ACCOUNT_ID="<keyID>"
export B2_ACCOUNT_KEY="<applicationKey>"

Permissions:

chmod 600 /etc/restic/env
chown root:root /etc/restic/env

Initialize the repository

source /etc/restic/env
restic init

One-time operation. After this, the bucket holds an encrypted restic repository ready to receive snapshots.

First backup

source /etc/restic/env
restic backup \
    --exclude-file=/etc/restic/excludes \
    /etc /home /var/lib /var/spool /root

Sample exclude file /etc/restic/excludes:

# System paths that change a lot and aren't worth backing up
/var/lib/mysql      # back up via mysqldump separately
/var/lib/postgresql # same
/var/cache
/var/tmp
/var/log
/proc
/sys
/dev
/tmp
/run
# Backup script's own scratch space
/var/lib/restic-tmp

Subsequent backups only upload changed file content thanks to deduplication. The first backup is the slow one.

Database dumps separately

Don't back up live database files directly — they'll be inconsistent. Dump first, back up the dump:

# MySQL/MariaDB
mysqldump --all-databases --single-transaction \
  | gzip > /var/backups/mysql-$(date +\%F).sql.gz

# PostgreSQL
sudo -u postgres pg_dumpall \
  | gzip > /var/backups/pg-$(date +\%F).sql.gz

Add /var/backups to your backup paths so the dumps go with everything else.

Schedule with systemd

Create /etc/systemd/system/restic-backup.service:

[Unit]
Description=Restic backup to B2
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStartPre=/usr/local/bin/db-dumps.sh
ExecStart=/usr/bin/restic backup --exclude-file=/etc/restic/excludes /etc /home /var/lib /var/spool /var/backups /root
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

And /etc/systemd/system/restic-backup.timer:

[Unit]
Description=Daily restic backup

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=30min

[Install]
WantedBy=timers.target

Enable:

systemctl daemon-reload
systemctl enable --now restic-backup.timer

Restoring

source /etc/restic/env

# List snapshots
restic snapshots

# Mount the repo and browse
mkdir /mnt/restic
restic mount /mnt/restic &
# Now /mnt/restic/snapshots/ has each snapshot as a dir tree

# Restore a specific snapshot
restic restore <snapshot-id> --target /restore

Test restore at least once after initial setup. A backup you've never restored from isn't a backup.

Cost estimate

For a typical PBX or small web VPS:

  • Initial backup: 5-20 GB.
  • Daily incremental: hundreds of MB to a few GB after dedup.
  • Storage cost at B2 rates: under $1/month for most small deployments.
  • Restore egress: also under $1 for a full restore at this scale.

For larger systems (multi-TB content), do the math against current B2 pricing.

Common mistakes

  • Storing the restic password on-VPS only. If the VPS is unrecoverable, you can't read your backups. Store the password in a password manager off- VPS too.
  • Not pruning. restic forget without --prune marks snapshots as forgotten but doesn't free B2 storage. Prune as part of the backup unit.
  • Backing up live DB files. Always dump first.
  • Untested restore. Restore to a scratch location at least once.

Also Read

« « Back

Powered by WHMCompleteSolution