Tutorials 10 min read

Automated Encrypted Backups with Restic and Backblaze B2 in 2026 (Complete Guide)

2026 tutorial on automating encrypted server backups to Backblaze B2 using restic. Covers encrypted repositories, systemd scheduling, retention policies, integrity checks, and restoration procedures to validate.

S By Selfhostr Team · no sponsored content
Automated Encrypted Backups with Restic and Backblaze B2 in 2026 (Complete Guide)
ⓘ ⓘ This article may contain affiliate links (no extra cost to you, it funds the site). As an Amazon Associate, Selfhostr earns from qualifying purchases. See the disclosure.
💰
~$6/TB/month
Cost
🆓
10 GB
Free Tier
🔒
Client-side
Encryption

👍 What we like

  • ✓Client-side encryption ensures provider cannot read data
  • ✓Low cost object storage with free tier for testing
  • ✓Automatic deduplication saves storage space
  • ✓Supports ransomware protection via versioning
  • ✓Integrity verification ensures backup reliability

👎 What to watch

  • ✕Passphrase loss makes data unrecoverable
  • ✕Requires manual setup of environment variables
  • ✕Bucket name must match region endpoint exactly
  • ✕No built-in GUI for management
📑 Contents ▾

There are two types of server administrators: those who back up, and those who will. A VPS hosting your Nextcloud, databases, or website is never immune to a failing disk, a rogue rm -rf command, ransomware, or a provider shutting down. The 3-2-1 rule (three copies, two media types, one off-site) remains the gold standard in 2026, and off-site copying is the one aspect most often neglected.

In this guide, we set up a serious, automatic, and encrypted backup strategy using restic, the Swiss Army knife of backups, to Backblaze B2, one of the cheapest object storage options on the market (approximately $6/TB/month). restic encrypts everything client-side before sending: even Backblaze cannot read your data. We cover repository initialization, deduplication, scheduling via systemd, automatic retention, integrity verification, and most importantly, restoration, because a backup that has never been restored is merely a hypothesis.

🖥️ Hardware to host it at home — To run this service 24/7 without a big power bill, a low-power mini PC is enough in most cases. Two common picks: the Beelink Mini S12 Pro (Intel N100, 16 GB) and the Beelink EQ14 (Intel N150, dual 2.5 GbE ports). To choose for your needs: our guide to the best mini PCs for a homelab.

Prerequisites

  • A Linux server (Ubuntu 24.04 / Debian 12) to back up. Ideally already hardened; see install and secure an Ubuntu VPS.
  • A Backblaze account: create one at backblaze.com. The first 10 GB of B2 are free, which is more than enough to test.
  • sudo access on the server.
  • A password manager to securely store the repository passphrase and B2 keys. If you lose the passphrase, your backups are unrecoverable by design.

If you are unsure about choosing the tool or object storage, our comparisons restic vs Borg vs Kopia and Backblaze B2 vs Wasabi vs Storj will help you decide.

Host your services

These backup solutions usually protect a self-hosted server. If you need a managed VPS to run your services, ready in minutes: See PlanetHoster plans

Step 1: Create a bucket and application key on Backblaze B2

Log in to your Backblaze account, then:

  1. Go to B2 Cloud Storage > Buckets > Create a Bucket.
  2. Give it a globally unique name (e.g., backup-srv-selfhostr-2026), set access to Private, and leave encryption as default.
  3. Note the bucket Endpoint displayed in its details (e.g., s3.eu-central-003.backblazeb2.com).
  4. Go to App Keys > Add a New Application Key.
  5. Restrict the key to your bucket only (principle of least privilege). Check both read and write permissions.
  6. Note the displayed keyID and applicationKey. The applicationKey is shown only once, so copy it immediately into your password manager.

Best practice: Enable versioning on the bucket (or object retention) on the Backblaze side. This provides additional protection against ransomware that encrypts/deletes your backups: even if the attacker accesses the key, previous versions remain recoverable.

Step 2: Install restic

restic is available in the repositories, but a recent version is better for the latest optimizations. On Ubuntu/Debian:

sudo apt update && sudo apt install -y restic

Check the version (aim for 0.16 or higher):

restic version

If the repository version is too old (Debian 12 ships a version older than 0.16), install the official binary: the self-update command is removed from the Debian and Ubuntu packages. Download the restic_<version>_linux_amd64.bz2 file from restic’s GitHub releases page, then:

bunzip2 restic_*_linux_amd64.bz2
sudo install -m 755 restic_*_linux_amd64 /usr/local/bin/restic
hash -r
restic version

This official binary can then update itself with sudo restic self-update.

Step 3: Configure environment variables

restic is controlled via environment variables for credentials and the passphrase. We store them in a protected file, readable only by root. Create the directory and file:

sudo mkdir -p /etc/restic
sudo nano /etc/restic/b2.env

restic communicates with Backblaze via the S3-compatible API. Fill in:

# S3 Endpoint for your bucket (from Step 1)
export RESTIC_REPOSITORY="s3:https://s3.eu-central-003.backblazeb2.com/backup-srv-selfhostr-2026"

# B2 Application Key credentials
export AWS_ACCESS_KEY_ID="YOUR_keyID"
export AWS_SECRET_ACCESS_KEY="YOUR_applicationKey"

# Repository encryption passphrase (long and unique!)
export RESTIC_PASSWORD="a-very-long-and-random-passphrase"

Lock down permissions; this file contains critical secrets:

sudo chmod 600 /etc/restic/b2.env
sudo chown root:root /etc/restic/b2.env

Common pitfall: The bucket name in RESTIC_REPOSITORY must match exactly, and the endpoint must be that of your region (the number after eu-central- varies). An error here results in an unhelpful Access Denied.

Step 4: Initialize the restic repository

Load the variables and initialize the encrypted repository (do this only once):

sudo bash -c 'source /etc/restic/b2.env && restic init'

You will receive a confirmation message with the repository ID. This is when the encrypted structure is created on Backblaze. From now on, all data sent is deduplicated and encrypted client-side with AES-256 before transfer.

Verify that the repository responds correctly:

sudo bash -c 'source /etc/restic/b2.env && restic snapshots'

The list is empty for now, but the absence of errors confirms that the credentials and passphrase are correct.

Step 5: First manual backup

Let’s back up typical server directories: application data, configuration, and Docker volumes. Adjust paths to your case:

sudo bash -c 'source /etc/restic/b2.env && restic backup \
  /etc \
  /home \
  /var/lib/docker/volumes \
  --exclude="/var/lib/docker/volumes/*/_data/cache" \
  --tag manual'

restic displays progress, the number of files, and the amount of data actually transferred (thanks to deduplication, only new or modified blocks go over the network). At the end, a new snapshot appears:

sudo bash -c 'source /etc/restic/b2.env && restic snapshots'

Backing up a database properly

Never copy database files while they are running: you risk a corrupted backup. Perform a dump and then back up the stream. Example PostgreSQL in a Docker container, piping directly to restic via stdin:

sudo bash -c 'source /etc/restic/b2.env && \
  docker exec mon-postgres pg_dumpall -U postgres | \
  restic backup --stdin --stdin-filename postgres-dump.sql --tag db'

For MySQL/MariaDB, replace with mysqldump --all-databases. This method guarantees a consistent, point-in-time backup.

Step 6: Automate with a script and systemd

We create a backup script that also includes retention cleanup. Create the file:

sudo nano /etc/restic/backup.sh
#!/usr/bin/env bash
set -euo pipefail
source /etc/restic/b2.env

# 1. Database dump
docker exec mon-postgres pg_dumpall -U postgres \
  | restic backup --stdin --stdin-filename postgres-dump.sql --tag db

# 2. File backup
restic backup /etc /home /var/lib/docker/volumes \
  --exclude-caches \
  --tag auto

# 3. Apply retention policy
restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune

Make it executable:

sudo chmod 700 /etc/restic/backup.sh

The retention policy above keeps the last 7 daily backups, 4 weekly, and 6 monthly, then --prune truly frees up space for data no longer referenced. A good balance between cost and history.

Create the systemd service and timer

systemd is more robust than a standard cron job (log management, dependencies, failure handling). Create the service unit:

sudo nano /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic backup to Backblaze B2
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/etc/restic/backup.sh
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7

Then the timer that triggers it every night:

sudo nano /etc/systemd/system/restic-backup.timer
[Unit]
Description=Launches daily restic backup

[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=900
Persistent=true

[Install]
WantedBy=timers.target

Persistent=true catches up on a missed backup if the server was off at the scheduled time. Enable the timer:

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

Check the schedule:

systemctl list-timers restic-backup.timer

Run an immediate execution to test the full script end-to-end:

sudo systemctl start restic-backup.service
journalctl -u restic-backup.service -n 50 --no-pager

Step 7: Verify backup integrity

A silently corrupted backup is worse than no backup. restic can check the repository integrity. A quick metadata check:

sudo bash -c 'source /etc/restic/b2.env && restic check'

For a thorough check that re-downloads and verifies a sample of actual data (recommended once a month):

sudo bash -c 'source /etc/restic/b2.env && restic check --read-data-subset=10%'

Step 8: Test restoration (the step always skipped)

This is the most important and most neglected step. Restore to a temporary location to validate that your data is recoverable:

# List snapshots and identify the desired ID
sudo bash -c 'source /etc/restic/b2.env && restic snapshots'

# Restore the latest snapshot to /tmp/restore-test
sudo bash -c 'source /etc/restic/b2.env && \
  restic restore latest --target /tmp/restore-test'

Inspect /tmp/restore-test and verify that your files are intact. To restore a single file or folder, use --include:

sudo bash -c 'source /etc/restic/b2.env && \
  restic restore latest --target /tmp/restore-test --include /etc/caddy/Caddyfile'

To restore a database dump, either mount the repository read-only or use restic dump:

sudo bash -c 'source /etc/restic/b2.env && \
  restic dump --tag db latest /postgres-dump.sql | docker exec -i mon-postgres psql -U postgres'

Schedule a real restoration test quarterly. This is the only way to be certain your strategy holds up.

Best practices and security

  • Keep the passphrase off the server. If the server is compromised, the attacker should not be able to read or destroy your backups. Ideally, the B2 key used by the server has only write (append-only) permission, not delete; in that case, remove forget --prune from the script and run it from another machine with a full key.
  • Enable object retention on Backblaze to make your backups immutable for a given window: ultimate ransomware protection.
  • Monitor failures. Couple the timer with an alert (email, webhook, or a Uptime Kuma “push” probe) to be notified if a backup fails. See our guide monitor your homelab with Uptime Kuma and Grafana.
  • Document the restoration procedure in a place accessible even if the server is dead (password manager, personal wiki).
  • Never put secrets in the script: the .env file with 600/root permissions is the correct place.

FAQ

Why restic instead of rsync or simple tar?

restic provides three things that tar or rsync do not offer natively: deduplication (identical blocks are stored only once, saving massive amounts of space), end-to-end encryption (your data is unreadable on the provider side), and versioning via snapshots with automatic retention. To compare with Borg and Kopia, read restic vs Borg vs Kopia in 2026.

How much does it really cost on Backblaze B2?

B2 charges approximately $6 per TB per month for storage, and outbound traffic (restoration) is free up to 3x the stored size each month. For a server whose deduplicated data fits in 50 GB, you pay a few tens of cents per month. The first 10 GB are free. It is one of the cheapest options, as shown in our B2 vs Wasabi vs Storj comparison.

What if I forget the repository passphrase?

Nothing. This is intentional: restic encrypts everything client-side; without the passphrase, there is no backdoor to decrypt it. Your backups become permanently unusable. This is why this passphrase must be stored in a reliable password manager, separate from the server, right from initialization.

Does the backup slow down my server?

Very little if you follow this guide. The Nice=10 and IOSchedulingClass=best-effort directives in the systemd service give restic low priority, yielding to application processes. By scheduling it at 3:30 AM, the impact is negligible for almost all use cases.

Can I back up multiple servers to the same repository?

Yes, and it is even an advantage: deduplication works across servers, so common files (system binaries, Docker images) are stored only once. Use distinct --tags per machine to keep things organized. However, be aware of concurrency: restic locks the repository during prune, so stagger the schedules.

Your data is now protected by an off-site, encrypted, deduplicated, and verifiable copy. All that remains is to test a restoration occasionally and sleep soundly. To follow new self-hosted tools and security best practices, join our Telegram watch bot.

Tags: resticbackblaze b2backupencryptionsystemdlinuxdata protection

Related

Tutorials

Backup Your NAS to an External Drive in 2026: Rotation, Encryption and Control

Back up a Synology NAS to an external USB drive with Hyper Backup: AES-256 client-side encryption, Smart Recycle rotation, two-drive rotation, integrity checks and a restore test.

Read
Tutorials

3-2-1 Backup with Restic: NAS + Encrypted Cloud Storage (2026)

Set up a real 3-2-1 backup with restic: an encrypted repository on your NAS over SFTP, an off-site copy in an S3-compatible bucket with restic copy, cron scheduling, and restore tests.

Read
Tutorials

Install Proxmox Backup Server in 2026: Incremental VM Backups

Install Proxmox Backup Server 4 on Debian 13: pbs-no-subscription repository, datastore, API token, PBS storage in Proxmox VE and scheduled incremental backups.

Read