Self-Hosted Backup Strategy for Homelab 2026: The Complete 3-2-1 Guide with Restic, Kopia & Duplicati

Reading time: ~18 minutes Audience: Homelab owners who have never tested a restore — and everyone who has data they cannot afford to lose


Introduction: The Most Common Homelab Regret

Go to any r/homelab or r/selfhosted thread titled “What do you wish you had done sooner?” and the top-voted answer is always the same: backups. Not VLAN segmentation. Not Kubernetes. Not 10 GbE networking. Backups.

The pattern is painfully consistent. A self-hoster spends months building a beautiful homelab — Proxmox hypervisor, Docker Compose stacks for Nextcloud, Jellyfin, Home Assistant, Pi-hole, Vaultwarden. Everything hums. Then one morning the boot SSD fails. Or a bad Docker volume mount overwrites a database. Or ransomware encrypts the media share. And there is no backup. Months of configuration, family photos, and carefully curated media libraries — gone.

The goal of this guide is simple: make sure that is never you. By the end, you will have a production-ready 3-2-1 backup strategy running in Docker Compose, covering your Docker volumes, Proxmox VMs, databases, and configuration files — with automated scheduling, encrypted offsite copies, and actual restore testing.

Already running Proxmox? See our Proxmox Beginner Guide if you need to set up your hypervisor first. New to Docker? Start with Nginx Proxy Manager Docker Compose for the compose fundamentals.


Why Every Homelab Needs a Backup Strategy (Now, Not Later)

Before we talk tools, let us talk about what failure actually looks like in a homelab:

Failure Scenario What You Lose Recovery Without Backup
Boot SSD corruption All VM configs, Docker volumes, OS Rebuild from scratch (days to weeks)
RAID controller failure Media library, documents Re-rip/re-download (months)
Accidental rm -rf /mnt/data Everything on that mount Zero — it is gone
Ransomware encrypts NFS share All files accessible to compromised container Pay ransom or lose everything
Failed Docker update destroys volume Application data, databases Rebuild app, lose all state
Proxmox node hardware failure All VMs on that node Rebuild every VM manually

The common thread: without backups, every one of these scenarios requires a full rebuild. With a proper 3-2-1 backup strategy, recovery takes hours — not weeks.

The Hidden Cost of NOT Backing Up

It is easy to think “I don’t have anything worth backing up — I can re-download my media and rebuild my configs.” Let us quantify that:

  • Configuration files: A typical homelab has 20–40 Docker Compose files, each with environment variables, volume mounts, and network configurations tested over weeks. Rebuilding them from scratch takes 10–20 hours.
  • Databases: Your Nextcloud database contains file metadata, shares, calendars, and contacts. Your Vaultwarden database holds every password. Rebuilding without a backup means starting over.
  • Media libraries: Even if you can re-download, a 4 TB media library takes weeks on a typical residential connection. And many items may no longer be available.
  • Family photos and documents: These are irreplaceable. A backup is the only insurance policy.

Understanding the 3-2-1 Backup Rule for Homelabs

The 3-2-1 rule is the gold standard of backup strategy, and it is deceptively simple:

Layer Rule What It Means for Your Homelab
3 Three copies of your data Primary data + local backup + offsite backup
2 Two different storage media Don’t put both backups on the same NAS or same disk type
1 One offsite copy Geographically separate — cloud, VPS, or a friend’s house

Why Each Layer Matters

Three copies protects against single-point-of-failure. If your primary data lives on one server and your backup lives on another — and both are the only copies — a fire or flood that takes both eliminates your data forever. Three copies gives you a buffer.

Two different media protects against correlated failures. If your primary data and backup both live on the same NAS with the same RAID array, a RAID controller failure or filesystem corruption can destroy both simultaneously. Different media means: primary on SSD, backup on HDD; or primary on NAS, backup on external USB drive.

One offsite copy protects against physical disasters. Fire, flood, theft, lightning strike — anything that destroys your physical location. An offsite copy in the cloud, on a VPS in another city, or even at a family member’s house ensures your data survives a worst-case scenario.

Common Mistakes That Break the 3-2-1 Rule

  1. Same-disk “backup”: Copying files to another folder on the same drive is not a backup. If the drive fails, both copies die.
  2. Live mirroring without versioning: A real-time mirror (RAID 1, rsync mirror, ZFS replication) is not a backup — it is redundancy. If ransomware encrypts the primary, it encrypts the mirror too. You need versioned, point-in-time snapshots.
  3. Never testing restores: A backup you have never restored is Schrödinger’s backup — it might work, or it might be a collection of corrupted files. You do not know until you test.
  4. No encryption on offsite copies: If your offsite backup lives on a cloud provider or a VPS, and it is not encrypted, anyone with access to that storage can read your data. Always encrypt before it leaves your network.

What to Back Up in a Homelab

Not everything in your homelab needs the same backup frequency or retention. Here is the practical checklist:

Backup Priority Checklist

Priority Data Type Examples Frequency Retention
🔴 Critical Databases, passwords Vaultwarden DB, Nextcloud DB, config files Daily 90 days
🔴 Critical Docker Compose files docker-compose.yml, .env files Daily (git) Forever
🟡 Important Docker volumes Nextcloud data, Home Assistant config, Immich uploads Daily 60 days
🟡 Important VM disk images Proxmox VM backups (PBS) Weekly 30 days
🟢 Nice-to-have Media libraries Jellyfin/Plex media Weekly 30–60 days
🟢 Nice-to-have ISO images, templates Proxmox ISOs, Docker images Monthly Keep latest

What NOT to Back Up

  • Docker images: These can be re-pulled from registries. Backing them up wastes space.
  • Transient caches: /tmp, browser caches, thumbnail caches.
  • Downloadable media: If you can re-download it quickly and it is not personal, skip it.

Pro tip: Store your Docker Compose files in a git repository. Push to Forgejo or GitHub after every change. This gives you infinite version history for free and is your first line of defense against misconfiguration.


The Big Three Self-Hosted Backup Tools: Restic vs Kopia vs Duplicati

The homelab backup tool landscape in 2026 has three clear leaders. Each excels in different scenarios. Here is the objective comparison:

Feature Comparison Matrix

Feature Restic Kopia Duplicati
First release 2015 2022 2014
Maturity 🔵 Very mature 🟡 Maturing fast 🔵 Very mature
Deduplication ✅ Excellent (content-defined chunking) ✅ Excellent (content-defined chunking) ⚠️ Good (block-level)
Compression LZ4, ZSTD ZSTD, S2 ZIP, 7z
Encryption AES-256-GCM, ChaCha20-Poly1305 AES-256-GCM, ChaCha20-Poly1305 AES-256
S3-compatible ✅ Native ✅ Native ✅ Native
Web UI CLI only ✅ Built-in web UI ✅ Built-in web UI
Docker-native ✅ Official image ✅ Official image ✅ LinuxServer image
Resource usage 🟢 Low (~50 MB RAM) 🟡 Medium (~200 MB RAM) 🔴 Higher (~300 MB RAM)
Snapshot browsing CLI mount GUI file browser GUI file browser
Retention policies ✅ Flexible ✅ Advanced ✅ Basic
Compression ratio ~2:1 typical ~2:1 typical ~1.5:1 typical
Repository repair restic repair ✅ Built-in maintenance ⚠️ Recreate database
Learning curve 🔴 Steep (CLI) 🟡 Moderate (GUI) 🟢 Easy (GUI)

Restic — The Command-Line Powerhouse

Restic is the tool of choice for technical users who want maximum control, efficiency, and reliability. It is written in Go, uses content-defined chunking for excellent deduplication, and supports virtually every storage backend.

Best for: Technical users comfortable with CLI, automation via cron, S3/B2 offsite backups, large datasets where deduplication matters.

Docker Compose snippet (scheduled backup with prune):

# docker-compose.yml — Restic scheduled backup
version: "3.8"
services:
  restic-backup:
    image: restic/restic:latest
    container_name: restic-backup
    environment:
      - RESTIC_REPOSITORY=s3:s3.amazonaws.com/bucket-name
      - RESTIC_PASSWORD=${RESTIC_PASSWORD}
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    volumes:
      - /opt/docker:/data:ro          # Docker volumes to back up
      - /etc/restic:/restic-config    # Exclude files, policy config
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        restic backup /data \
          --exclude-file=/restic-config/excludes.txt \
          --tag docker-volumes \
          && restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune \
          && restic check
    restart: unless-stopped

Kopia — The Modern GUI-Friendly Option

Kopia is the newest entrant and has rapidly gained traction because of its polished web UI, advanced snapshot policies, and multi-repository support. If you want a GUI to browse snapshots and restore individual files without remembering CLI flags, Kopia is the answer.

Best for: Users who want a web UI, complex retention policies per dataset, graphical snapshot browsing, multi-repo management.

Docker Compose snippet (Kopia server mode with web UI):

# docker-compose.yml — Kopia server with web UI
version: "3.8"
services:
  kopia:
    image: kopia/kopia:latest
    container_name: kopia-server
    hostname: kopia
    environment:
      - KOPIA_PASSWORD=${KOPIA_PASSWORD}
      - USER=kopia
    ports:
      - "51515:51515"
    volumes:
      - ./kopia-config:/app/config
      - ./kopia-cache:/app/cache
      - /opt/docker:/data:ro
      - /mnt/backup-nas:/backup-local
    command:
      - server
      - start
      - --insecure
      - --address=0.0.0.0:51515
      - --server-username=kopia
      - --server-password=${KOPIA_PASSWORD}
    restart: unless-stopped

Duplicati — The Beginner’s Choice

Duplicati is the easiest to set up: a single Docker container with a web UI, a setup wizard, and support for dozens of backends out of the box. It is the “install in 5 minutes and forget about it” option.

Best for: Beginners, quick setup, diverse backend support, users who want a familiar GUI wizard.

Docker Compose snippet (LinuxServer Duplicati):

# docker-compose.yml — Duplicati with web UI
version: "3.8"
services:
  duplicati:
    image: lscr.io/linuxserver/duplicati:latest
    container_name: duplicati
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Jakarta
      - CLI_ARGS=
    volumes:
      - ./duplicati-config:/config
      - /opt/docker:/source:ro
      - /mnt/backup-nas:/backup
    ports:
      - "8200:8200"
    restart: unless-stopped

Which one should you choose? If you are comfortable with CLI, pick Restic. If you want a GUI without sacrificing performance, pick Kopia. If you are new and want the easiest path, start with Duplicati and consider migrating to Restic or Kopia as your needs grow.


Building Your 3-2-1 Homelab Backup Stack

Now let us assemble the complete stack, layer by layer.

Layer 1 — Primary Data (Your Production Environment)

This is where your data lives: - Docker host: /opt/docker with all Compose files and volumes - Proxmox host: VM disk images on local-lvm or ZFS - NAS: Media library, document shares, ISO storage

Layer 2 — Local Backup (On-Site, Different Media)

Your first backup copy should live on different physical hardware:

Option Cost Capacity Complexity
External USB HDD (8–20 TB) $150–$400 High Low
Dedicated backup NAS (used) $200–$500 High Medium
Proxmox Backup Server (PBS) $0 (software) + HW Configurable Medium
Old PC with TrueNAS $0–$200 High Medium
Raspberry Pi + SATA HAT + HDD $80–$200 1–8 TB Medium

NFS mount for NAS backup target (add to /etc/fstab):

# /etc/fstab — Mount NAS share for backup target
192.168.50.100:/mnt/tank/backups  /mnt/backup-nas  nfs  rw,hard,intr,noatime  0  0

Layer 3 — Offsite Backup (Geographically Separate)

Your third copy must be physically separate from your homelab. Here are the best options for self-hosters in 2026:

Provider Type Free Tier Paid From Best For
Backblaze B2 S3-compatible object storage 10 GB $6/TB/month Restic/Kopia S3 target
Cloudflare R2 S3-compatible object storage 10 GB $0.015/GB/month Zero egress fees
Hetzner StorageBox SFTP/rsync/Borg €3.81/month for 1 TB Simple rsync target
BuyVM + Slab VPS + attached storage $5/month for 256 GB Self-hosted offsite node
Hetzner CX22 VPS VPS with 1 TB block storage ~€6/month Self-hosted backup server

Restic S3 repository configuration (Backblaze B2 example):

# Set up a new Restic repository on Backblaze B2
export RESTIC_REPOSITORY="s3:s3.us-west-004.backblazeb2.com/homelab-backups"
export RESTIC_PASSWORD="your-strong-password-here"
export AWS_ACCESS_KEY_ID="your-b2-key-id"
export AWS_SECRET_ACCESS_KEY="your-b2-application-key"

restic init

Rsync to Hetzner StorageBox script:

#!/bin/bash
# rsync-backup.sh — Backup docker volumes to Hetzner StorageBox via rsync
STORAGEBOX="[email protected]"
REMOTE_PATH="/home/backups/docker"
LOCAL_PATH="/opt/docker"
LOG_FILE="/var/log/backup-rsync.log"

echo "[$(date)] Starting rsync backup to StorageBox..." >> "$LOG_FILE"
rsync -avz --delete \
    --exclude="*.log" \
    --exclude="cache/" \
    "$LOCAL_PATH/" "$STORAGEBOX:$REMOTE_PATH/" \
    >> "$LOG_FILE" 2>&1

if [ $? -eq 0 ]; then
    echo "[$(date)] Backup completed successfully." >> "$LOG_FILE"
else
    echo "[$(date)] Backup failed with exit code $?" >> "$LOG_FILE"
    # Send notification (ntfy, Discord, email — see monitoring section)
fi

Proxmox-Specific Backup Strategy

If you run Proxmox as your hypervisor, you have two additional backup paths:

Proxmox Backup Server (PBS)

PBS is a dedicated backup appliance (free, open-source) that provides incremental, deduplicated VM and container backups with a web UI. It is purpose-built for Proxmox and handles dirty-bitmap incremental backups — meaning after the first full backup, subsequent backups only transfer changed blocks.

PBS Docker Compose (for running PBS as a container on a backup node):

# docker-compose.yml — Proxmox Backup Server
version: "3.8"
services:
  pbs:
    image: ayufan/proxmox-backup-server:latest
    container_name: pbs
    hostname: pbs
    network_mode: host
    privileged: true
    volumes:
      - ./pbs-config:/etc/proxmox-backup
      - ./pbs-datastore:/backup-datastore
      - ./pbs-logs:/var/log/proxmox-backup
    restart: unless-stopped

VM Backup Schedule Recommendations

VM Type Backup Method Frequency Retention
Critical VMs (firewall, DNS) PBS + Restic to offsite Daily 30 days
Application VMs (Nextcloud, Vaultwarden) PBS Daily 30 days
Development VMs PBS Weekly 14 days
Media server VMs PBS Weekly 14 days

Testing Your Backups (The Step Everyone Skips)

A backup you have never restored is not a backup — it is a hope. Every backup tool can produce corrupted output if disk errors, memory faults, or software bugs intervene.

The Quarterly Backup Fire Drill

Once every three months, run this checklist:

  1. Pick a random backup snapshot — do not pick the most recent one, pick one from 30 days ago. This tests your retention policies and ensures older snapshots are not silently corrupted.
  2. Restore to a test directory — never restore over production data.
  3. Verify file integrity — compare checksums with the original if possible.
  4. Start the restored application — spin up a Docker container from the restored config and verify it works.
  5. Document the result — a simple log entry: “2026-06-07: restored Nextcloud backup from 2026-05-07. All files verified. Database started successfully.”

Restic restore test script:

#!/bin/bash
# test-restore.sh — Restore a random snapshot to /tmp and verify
SNAPSHOT=$(restic snapshots --json | jq -r '.[-5].id')  # 5th newest
RESTORE_DIR="/tmp/restic-restore-test-$(date +%Y%m%d)"

echo "Testing restore of snapshot: $SNAPSHOT"
mkdir -p "$RESTORE_DIR"
restic restore "$SNAPSHOT" --target "$RESTORE_DIR"

if [ $? -eq 0 ]; then
    echo "✅ Restore successful. Files in: $RESTORE_DIR"
    echo "📊 File count: $(find "$RESTORE_DIR" -type f | wc -l)"
    echo "📊 Total size: $(du -sh "$RESTORE_DIR" | cut -f1)"
else
    echo "❌ Restore FAILED. Check restic logs immediately."
fi

Disaster Recovery Scenarios

Let us walk through five real disaster scenarios and how your 3-2-1 strategy handles each:

Scenario RTO (Recovery Time) RPO (Data Loss) Recovery Path
Primary server SSD failure 2–4 hours 0–24 hours Restore Docker volumes from local NAS backup. Rebuild OS from Ansible/Terraform.
Ransomware encrypts everything 4–8 hours 0–24 hours Wipe infected systems. Restore from air-gapped or versioned backup. Offsite copy must be immutable or pull-only.
NAS hardware failure 1–2 days (if replacing HW) 0 hours All primary data on Docker host unaffected. Restore NAS from offsite backup or PBS.
Offsite provider goes down 0 hours (no data loss) N/A Set up new offsite target. Push fresh backup. Meanwhile, local backup still protects you.
Accidental deletion (30 days ago) 1–2 hours 0 (if versioned) Browse versioned snapshots. Restore the specific file or directory from before the deletion.

RTO (Recovery Time Objective): How long it takes to recover. RPO (Recovery Point Objective): How much data you can afford to lose (measured in time).


Security & Encryption Best Practices

Backups contain your most sensitive data — passwords, personal documents, family photos. Every backup copy, especially offsite copies, must be encrypted.

Encryption Checklist

Layer Requirement Tool
At rest (local) Encrypt backup target disk LUKS, ZFS native encryption
In transit Encrypt network traffic TLS (Restic/Kopia), SSH (rsync), WireGuard/Tailscale
At rest (offsite) Encrypt backup data before it leaves Restic/Kopia built-in encryption
Key management Store encryption keys separately from data Password manager, offline paper backup
Key backup Ensure keys are recoverable Printed QR code of encryption key in a safe deposit box or with a trusted person

Immutable Backups for Ransomware Protection

Restic supports append-only repositories when using the REST server backend. Kopia supports object lock with S3-compatible storage. This means even if an attacker compromises your backup server, they cannot delete or modify existing snapshots — they can only add new ones, and only until the lock expires.


Cost Comparison: Building a Backup Stack on a Budget

You can build a working 3-2-1 backup strategy at almost any budget level:

Tier Monthly Cost What You Get Safety Level
$0 Free Local backup to spare USB HDD. Manual offsite rotation to a drive stored at work/family. 🟡 Low (manual, no automation)
$5 ~$5/month Hetzner StorageBox 1 TB + local USB HDD. Automated rsync or Restic. 🟢 Good for configs + databases
$15 ~$15/month Backblaze B2 2 TB + local backup + PBS. Fully automated 3-2-1. 🟢 Excellent for most homelabs
$50 ~$50/month Dedicated backup VPS + cloud storage + local NAS. Multi-site automated. 🔵 Enterprise-grade redundancy

The sweet spot for most homelabs: $5–$15/month. A Hetzner StorageBox (€3.81 for 1 TB) for offsite, a spare USB HDD for local backup, and Restic (free) for automation gives you a fully automated 3-2-1 setup for under $5/month.


Maintenance & Monitoring

A backup strategy is not “set and forget.” It requires monitoring to catch failures before you need a restore.

Backup Health Dashboard with Uptime Kuma

Monitor each backup job with Uptime Kuma push monitors. If a job does not report in within its expected window, you get an alert:

#!/bin/bash
# backup-health-check.sh — Run after each backup job
BACKUP_NAME="docker-restic-daily"
KUMA_PUSH_URL="https://uptime.yourdomain.com/api/push/abc123?status=up&msg=OK"

# ... backup commands here ...

if [ $? -eq 0 ]; then
    curl -s "$KUMA_PUSH_URL&msg=Backup+${BACKUP_NAME}+completed+successfully"
else
    curl -s "${KUMA_PUSH_URL}&status=down&msg=Backup+${BACKUP_NAME}+FAILED"
fi

Full monitoring setup: See our Uptime Kuma Docker Compose guide for the complete deployment and notification configuration.

Monthly Backup Health Check Routine

  • [ ] Review backup logs for errors and warnings
  • [ ] Check disk usage trends (are backups growing unexpectedly?)
  • [ ] Verify retention policies are pruning old snapshots
  • [ ] Run a spot restore test on one random file
  • [ ] Verify offsite copy is reachable and up to date
  • [ ] Rotate encryption key backup if keys have changed

Which Backup Tool Should You Choose? Decision Matrix

Your Profile Recommended Tool Why
“I just want it to work — I’m new” Duplicati Web UI wizard, 5-minute setup, broad backend support
“I live in the terminal” Restic Fastest, most mature, best S3 support, excellent dedup
“I want a GUI + power” Kopia Web UI with advanced policies, snapshot browsing, multi-repo
“I only backup Proxmox VMs” Proxmox Backup Server Purpose-built, dirty-bitmap incremental, web UI
“I need versioned file-level backup with dedup” Restic or BorgBackup Both excellent; Restic has better cloud/S3 support
“I backup to NAS only, no cloud” Kopia (server mode) Web UI, local repository, snapshot policies
“I want zero-knowledge cloud backup” Restic Client-side encryption, all cloud providers supported

The Beginner Path

Start with Duplicati (easiest setup, web UI wizard). Once you understand backup concepts — snapshots, retention, deduplication — migrate to Kopia or Restic for better performance and reliability.

The Power User Path

Start with Restic from day one. The CLI learning curve is worth it for the performance, reliability, and flexibility. Use the shell scripts in this guide as templates.


Conclusion: Start With ONE Backup Today

The most important backup is the one you actually run. Do not let analysis paralysis stop you from taking the first step. Here is a concrete 15-minute action plan:

  1. Right now: Copy your Docker Compose files to a git repository and push. This is zero-cost and protects your most valuable configuration data immediately.
  2. Today: Plug in a spare external HDD and run a manual restic backup of /opt/docker. One command: restic init --repo /mnt/backup && restic backup /opt/docker.
  3. This week: Set up the Docker Compose configuration from this guide (Restic, Kopia, or Duplicati — pick one). Schedule it via cron or the tool’s built-in scheduler.
  4. This month: Add an offsite target. A Hetzner StorageBox costs €3.81/month and gives you a true 3-2-1 strategy.
  5. This quarter: Run your first restore test. Pick a random snapshot and restore it to /tmp. Verify the files are intact.

Your future self — the one who accidentally deletes the wrong directory, survives a hardware failure, or faces a ransomware attack — will thank you.


Related Articles