Restic + Docker Volume Backup to Backblaze B2
A configurable, self-contained Bash utility to back up both regular files and Docker volumes using Restic to Backblaze B2 cloud storage.
It supports:
- File and directory backups
- Docker volume exports as
.tar.gz - Encrypted configuration bundles for disaster recovery
- Automatic pruning and integrity checks
- Cron-based scheduling
- One-command restore (for both files and volumes)
Features
- Config-driven: all backup targets defined in
/etc/restic/files — no script edits required. - Docker-aware: automatically dumps volumes via temporary BusyBox containers.
- Encrypted config backup: one-command bundle of env, config, and cron.
- Disaster-ready: restore the entire backup environment on a new host in minutes.
- Locking + logging: safe for cron usage; no overlapping runs.
- Backblaze B2 native: works with B2 buckets via Restic’s B2 backend.
Directory Structure
| Path | Purpose |
|---|---|
/usr/local/bin/backup-to-b2.sh |
Main backup script |
/etc/restic/env |
Restic + B2 credentials |
/etc/restic/files.list |
Files/directories to back up |
/etc/restic/volumes.list |
Docker volumes to back up |
/etc/restic/excludes.txt |
Optional Restic exclude patterns |
/etc/cron.d/backup-to-b2 |
Cron job definition |
/var/backups/staging/volumes/ |
Temp tarballs of Docker volumes |
/var/backups/restic-config/ |
Encrypted config bundle archives |
/var/log/backup/ |
Backup logs |
Installation
-
Copy script
sudo cp backup-to-b2.sh /usr/local/bin/ sudo chmod +x /usr/local/bin/backup-to-b2.sh -
Create
/etc/restic/directorysudo mkdir -p /etc/restic sudo chmod 700 /etc/restic -
Edit configuration files
/etc/restic/envexport RESTIC_REPOSITORY="b2:my-bucket:servers/$(hostname)" export RESTIC_PASSWORD="super-long-passphrase" export B2_ACCOUNT_ID="001234567890" export B2_ACCOUNT_KEY="your-b2-app-key"/etc/restic/files.list/etc /home /var/www/etc/restic/volumes.listmariadb_data redis_cache/etc/restic/excludes.txt*.tmp **/node_modules *.iso /var/www/cache -
Create cron schedule
/etc/cron.d/backup-to-b2SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MAILTO="" 30 2 * * * root /usr/local/bin/backup-to-b2.sh run >> /var/log/backup/cron.log 2>&1
Usage
Run backup manually
sudo /usr/local/bin/backup-to-b2.sh run
Dry run (show what would be backed up)
sudo /usr/local/bin/backup-to-b2.sh dry-run
Clean staging (remove old tarballs)
sudo /usr/local/bin/backup-to-b2.sh clean
Create encrypted config backup
sudo /usr/local/bin/backup-to-b2.sh make-config-backup
Creates /var/backups/restic-config/restic-config-YYYYMMDD_HHMMSS.tar.gz.enc
Decrypt config backup
sudo /usr/local/bin/backup-to-b2.sh decrypt-config-backup /path/to/restic-config-2025XXXX.tar.gz.enc
Add --restore to overwrite /etc/restic, cron, and script:
sudo /usr/local/bin/backup-to-b2.sh decrypt-config-backup /path/to/file.enc --restore
Restore Docker volume from latest snapshot
sudo /usr/local/bin/backup-to-b2.sh restore-volume-from-repo mariadb_data latest
Restore plain tarball into volume
sudo /usr/local/bin/backup-to-b2.sh restore-volume mariadb_data /var/backups/staging/volumes/mariadb_data.tar.gz
Environment Variables
| Variable | Description |
|---|---|
RESTIC_REPOSITORY |
B2 repo URL (b2:bucket:prefix) |
RESTIC_PASSWORD |
Restic encryption password |
B2_ACCOUNT_ID |
B2 application key ID |
B2_ACCOUNT_KEY |
B2 application key |
CONFIG_ARCHIVE_PASSPHRASE |
Passphrase for encrypt/decrypt config bundles (optional) |
CONFIG_BACKUP_B2_URL |
Upload target for config bundles (b2://bucket/prefix) |
Restore a fresh system
1: Install dependencies
sudo apt install -y docker.io restic busybox openssl
2: Decrypt your saved config
openssl enc -d -aes-256-cbc -pbkdf2 -in restic-config-2025XXXX.tar.gz.enc -out restic-config.tar.gz
sudo tar xzf restic-config.tar.gz -C /
3: Fix permissions
sudo chmod 600 /etc/restic/env
sudo chmod +x /usr/local/bin/backup-to-b2.sh
4: Verify access
source /etc/restic/env
restic snapshots
5: Restore data
-
Files:
restic restore latest --target /restore -
Docker volume:
./backup-to-b2.sh restore-volume-from-repo mariadb_data latest
Security Best Practices
- Keep
/etc/restic/envchmod 600and owned by root. - Store your Restic password offline; it cannot be recovered.
- Use unique Backblaze B2 Application Keys per server.
- Periodically rotate your keys and regenerate
/etc/restic/env. - Store your encrypted config bundle (
.enc) offsite or in your B2 bucket under a separate prefix.
Logs & Diagnostics
| File | Purpose |
|---|---|
/var/log/backup/backup.log |
Detailed script log |
/var/log/backup/cron.log |
Cron job output |
/var/lock/backup-to-b2.lock |
Prevents concurrent backups |
View last backup:
sudo tail -n 50 /var/log/backup/backup.log
Tips
-
Test restores regularly using
--target /tmp/test-restore. -
Run
restic checkmonthly to verify repo integrity. -
You can initialize multiple hosts in the same B2 bucket with unique prefixes.
-
To start over with a clean repo:
b2 sync --delete /tmp/empty b2://my-bucket/servers/hostname restic init
License
MIT © 2025
Description
Languages
Shell
100%