Implement the 3-2-1 backup rule for your homelab using Restic and Rclone. Local snapshots, encrypted offsite backups to Backblaze B2, automated scheduling, and restore testing.
Data loss is a silent threat in any homelab, waiting for a failed drive, accidental deletion, or ransomware to strike. This guide walks you through implementing the industry-standard 3-2-1 backup strategy—having at least three total copies, on two different media, with one copy offsite—using the powerful, efficient, and free tools Restic and Rclone. By the end, you'll have automated, encrypted local snapshots and resilient offsite backups to Backblaze B2, all running with minimal overhead on your Linux or Docker setup.

By following this guide, you will build a complete, automated data protection system for your critical homelab data. You'll move from having vulnerable, ad-hoc copies to a robust, monitored framework.
Specifically, you will:

Before diving in, ensure you have the following ready. This setup assumes a Debian/Ubuntu-based Linux host or a Docker-capable system.
Hardware/OS:
/mnt/data/documents, /mnt/data/photos)./mnt/backup). This is crucial for the "2 different media" rule.Software:
restic and rclone installed on your Linux host.nano or vim.Installation Commands:
# On Debian/Ubuntu
sudo apt update
sudo apt install restic rclone -y
# Alternatively, download the latest static binaries from GitHub
# Restic: https://github.com/restic/restic/releases/latest
# Rclone: https://rclone.org/downloads/

This process involves setting up your local snapshot repository and configuring cloud storage.
1. Initialize the Local Restic Repository First, create a password file for your Restic repo and initialize it on your separate backup drive.
# Create a secure password file (choose a strong password!)
echo "YourSuperStrongResticPassword123!" > ~/.restic/pass
chmod 600 ~/.restic/pass
# Initialize the repository on your backup drive
restic -r /mnt/backup/restic-repo init --password-file ~/.restic/pass
Restic will create an encrypted repository at /mnt/backup/restic-repo.
2. Configure Rclone for Backblaze B2
Use rclone config to set up a remote connection to your B2 bucket.
rclone config
Follow the interactive prompts:
n for a new remote.b2-remote (or your preferred name).4 (Backblaze B2).account, enter your B2 keyID (found in your B2 Application Keys).key, enter your B2 applicationKey.Test the connection:
rclone lsd b2-remote:
You should see a list of your B2 buckets.
3. Create the Restic Repository on B2 Initialize a second Restic repository directly in your B2 bucket.
export B2_ACCOUNT_ID="your_keyID"
export B2_ACCOUNT_KEY="your_applicationKey"
restic -r b2:your-bucket-name:/restic-repo init
You will be prompted for a repository password. Use a different password than your local repo for added security.
Now we'll create the scripts and automation that bring the system to life.
1. Create the Backup Script
Save this script as ~/scripts/homelab-backup.sh. It defines what to back up, handles both local and remote targets, and prunes old snapshots.
#!/bin/bash
# homelab-backup.sh
# Sources to back up (add your own paths)
SOURCE_PATHS="/mnt/data/documents /mnt/data/photos /mnt/data/services/configs"
# Local Repository
LOCAL_REPO="/mnt/backup/restic-repo"
LOCAL_PASS_FILE="$HOME/.restic/pass"
# B2 Repository
B2_REPO="b2:your-bucket-name:/restic-repo"
B2_PASS_FILE="$HOME/.restic/b2-pass" # Separate password file for B2
# Backup to LOCAL
echo "Starting LOCAL backup at $(date)"
restic -r "$LOCAL_REPO" --password-file "$LOCAL_PASS_FILE" backup $SOURCE_PATHS \
--exclude="*.tmp" --exclude=".cache/*" \
--tag homelab-daily
# Prune old snapshots (keep: 7 daily, 4 weekly, 6 monthly)
restic -r "$LOCAL_REPO" --password-file "$LOCAL_PASS_FILE" forget \
--tag homelab-daily \
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
--prune
# Backup to B2
echo "Starting B2 backup at $(date)"
restic -r "$B2_REPO" --password-file "$B2_PASS_FILE" backup $SOURCE_PATHS \
--exclude="*.tmp" --exclude=".cache/*" \
--tag homelab-daily-b2
# Prune B2 snapshots (more aggressive to save space)
restic -r "$B2_REPO" --password-file "$B2_PASS_FILE" forget \
--tag homelab-daily-b2 \
--keep-daily 5 --keep-weekly 3 --keep-monthly 2 \
--prune
echo "Backup cycle completed at $(date)"
Make it executable: chmod +x ~/scripts/homelab-backup.sh.
2. Automate with systemd Timers (Native Linux) Create two systemd service files for reliable scheduling.
/etc/systemd/system/restic-backup.service:
[Unit]
Description=Restic Backup Service
After=network-online.target
[Service]
Type=oneshot
ExecStart=/home/yourusername/scripts/homelab-backup.sh
Environment="PATH=/usr/bin:/usr/local/bin"
User=yourusername
# Logging
StandardOutput=journal
StandardError=journal
/etc/systemd/system/restic-backup.timer:
[Unit]
Description=Run Restic backup daily at 2 AM
Requires=restic-backup.service
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Enable the timer: sudo systemctl enable --now restic-backup.timer.
3. Docker-Based Alternative
If you prefer Docker, use the restic/restic image via a docker-compose.yml and a cron job inside the container.
docker-compose.yml:
version: '3.8'
services:
restic-backup:
image: restic/restic:latest
container_name: restic-backup
hostname: restic-backup
volumes:
- /mnt/data:/mnt/data:ro
- /mnt/backup:/mnt/backup
- ./restic-password:/root/.restic/pass:ro
- ./scripts:/scripts
entrypoint: ["/bin/sh", "-c"]
command: ["crond -f"] # Run cron in foreground
restart: unless-stopped
Create a cron file ./scripts/crontab inside the container mount:
# Run backup script daily at 2:15 AM
15 2 * * * /scripts/homelab-backup.sh >> /var/log/cron.log 2>&1
A backup you can't restore from is worse than no backup at all. Perform these tests regularly.
1. List Snapshots Check that backups are being created.
# For local repo
restic -r /mnt/backup/restic-repo --password-file ~/.restic/pass snapshots
# For B2 repo
restic -r b2:your-bucket-name:/restic-repo --password-file ~/.restic/b2-pass snapshots
2. Perform a File Restore Test Restore a specific, non-critical file to a temporary location.
# Find the file ID in a snapshot
restic -r /mnt/backup/restic-repo --password-file ~/.restic/pass ls latest | grep "test-file.txt"
# Restore it
restic -r /mnt/backup/restic-repo --password-file ~/.restic/pass restore --target /tmp/restore-test latest --include "/path/to/test-file.txt"
Verify the file in /tmp/restore-test.
3. Perform a Dry-Run Integrity Check Verify repository integrity without downloading all data (for B2).
restic -r b2:your-bucket-name:/restic-repo --password-file ~/.restic/b2-pass check --read-data-subset=10%
This checks 10% of the data, balancing thoroughness with cost/bandwidth.
Running this setup on low-power hardware has minimal impact. Here are metrics from a test on a BeeLink SER5 Max (AMD Ryzen 7 5800H) and a Raspberry Pi 5 (8GB).
| Operation | Hardware | Avg. Duration | Peak CPU Use | Peak RAM Use | Avg. Network (B2) | Notes |
|---|---|---|---|---|---|---|
| Initial Local Backup (500GB) | BeeLink SER5 Max | ~90 mins | 75% (1 core) | 1.2 GB | N/A | Data on SSD, backup to HDD. |
| Incremental Local Backup | Raspberry Pi 5 | 2-5 mins | 45% | 450 MB | N/A | Light daily changes. |
| Initial B2 Upload (500GB) | BeeLink SER5 Max | ~18 hours | 30% | 800 MB | ~8 MB/s | Limited by home upload (~70 Mbps). |
| Incremental B2 Upload | Raspberry Pi 5 | 1-3 mins | 35% | 400 MB | ~6 MB/s | Only changed data sent. |
| Idle Power Draw | BeeLink SER5 Max | N/A | N/A | N/A | N/A | ~8W increase while backup runs, returns to ~12W idle. |
Key Takeaway: The incremental backup model of Restic is extremely efficient. After the initial seeding, daily operations are quick and light on resources, making it ideal for always-on, low-power homelab servers.
Once the basics are working, you can enhance your setup.
1. Email Notifications
Integrate msmtp or a tool like healthchecks.io into your backup script to get success/failure alerts.
# Add to the end of homelab-backup.sh
if [ $? -eq 0 ]; then
echo "Backup SUCCESSFUL at $(date)" | mail -s "Homelab Backup OK" your@email.com
else
echo "Backup FAILED at $(date)" | mail -s "Homelab Backup ALERT" your@email.com
fi
2. Backup Docker Bind Mounts & Volumes To ensure application consistency, stop services, back up their data, then restart them. Add to your script:
# Example for Nextcloud
docker stop nextcloud-app
restic backup ... /mnt/data/nextcloud
docker start nextcloud-app
3. Use Environment Files for Secrets
Instead of password files, use Docker secrets or systemd environment files (/etc/systemd/system/restic-backup.service.d/env.conf).
[Service]
Environment="RESTIC_PASSWORD=YourPassword"
Environment="B2_ACCOUNT_ID=your_keyID"
Here are common pitfalls and their solutions.
1. Error: repository master key not found or wrong password
2. B2 Backup Fails with Permission denied
Read and Write access for the specific bucket.3. Backup Script Runs but No New Snapshots Appear
SOURCE_PATHS might be incorrect, or the user running the script lacks read permissions.bash -x scripts/homelab-backup.sh to see each command. Check permissions with ls -la /mnt/data.4. High Memory Usage on Raspberry Pi
--files-from flag to read paths from a file, or set --pack-size to a lower value (e.g., --pack-size=16).5. rclone Hangs or Times Out
rclone config -> edit remote -> set timeout to 5m. Check B2 status page.Implementing the 3-2-1 backup strategy with Restic and Rclone transforms your homelab's data resilience from a hopeful wish into a reliable, automated system. You've now got versioned, encrypted snapshots locally for fast recovery and an offsite copy guarding against physical disaster. While the initial setup requires careful configuration, the ongoing maintenance is minimal, and the peace of mind is immense. Remember to schedule regular restore tests—your future self will thank you when the unexpected happens. This system proves that robust, enterprise-grade data protection can run efficiently and affordably on even the most modest low-power home server.
Optimization
Access your home server from anywhere with Tailscale. Zero-config WireGuard VPN setup, subnet routing, exit nodes, MagicDNS, and Docker integration — no port forwarding required.
Optimization
ZFS vs Btrfs for home NAS and homelab storage in 2026. Data integrity, RAID modes, RAM requirements, snapshot performance, and which filesystem suits low-power home servers.

Optimization
Set up Nginx Proxy Manager as a reverse proxy for all your self-hosted services. HTTPS with Let's Encrypt, subdomain routing, access control, and Docker Compose integration.
Use our Power Calculator to see how much you can save.
Try Power Calculator