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
- Sign up at backblaze.com/b2.
- Create an application key with read+write+list permissions limited to a specific bucket.
- Create the bucket. Name it something specific to this VPS (e.g.,
backup-pbx-prod-2026). Private access only. - 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 forgetwithout--prunemarks 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
Powered by WHMCompleteSolution