You’re running a home server with important data — photos, documents, databases, configurations. What happens when a drive dies? When you accidentally rm -rf the wrong directory? When ransomware hits?

Restic + Rclone is the gold standard backup combo for self-hosters. Restic creates fast, encrypted, deduplicated snapshots. Rclone syncs them to any cloud provider. Together, they give you enterprise-grade backups for free.

The 3-2-1 Backup Rule

Before we start, understand the rule that prevents data loss:

  • 3 copies of your data
  • 2 different storage types (local + cloud)
  • 1 offsite copy (cloud or remote server)

Our setup achieves all three: original data + local Restic repo + Rclone cloud sync.

What You’ll Build

  • Restic — incremental, encrypted, deduplicated backups to a local repository
  • Rclone — syncs the backup repo to cloud storage (Backblaze B2, S3, Google Drive, etc.)
  • Automated schedule — cron job runs backups daily
  • Retention policy — keeps daily/weekly/monthly snapshots automatically

Prerequisites

  • Linux server (Ubuntu/Debian)
  • ~100MB RAM for backup operations
  • External drive or second disk for local backups (recommended)
  • Cloud storage account (Backblaze B2 is cheapest at $0.005/GB/month)

Step 1: Install Restic

# Ubuntu/Debian
sudo apt install restic

# Or get the latest binary
wget https://github.com/restic/restic/releases/latest/download/restic_0.17.3_linux_arm64.bz2
bunzip2 restic_*.bz2
chmod +x restic_*
sudo mv restic_* /usr/local/bin/restic

Verify:

restic version

Step 2: Initialize the Backup Repository

Choose where to store backups locally:

# On an external drive or second disk
sudo mkdir -p /mnt/backups/restic-repo

# Initialize with a strong password
export RESTIC_PASSWORD="your-strong-password-here"
restic init --repo /mnt/backups/restic-repo

Save this password somewhere safe. Without it, your backups are unrecoverable. Consider storing it in your password manager and printing a physical copy.

Step 3: Create Your First Backup

# Backup your important directories
restic -r /mnt/backups/restic-repo backup \
  /home/user/documents \
  /var/www \
  /opt/docker \
  --exclude="*.tmp" \
  --exclude="node_modules" \
  --exclude=".cache"

Restic deduplicates automatically — if a file hasn’t changed, it won’t be stored again. Your second backup will be much faster than the first.

What to Back Up

PriorityWhatWhy
CriticalDocker volumes, databasesService data
Critical/home directoriesPersonal files
HighDocker compose filesService configs
High/etcSystem configuration
MediumNginx/Caddy configsReverse proxy setup
LowContainer imagesCan re-pull from registries

What NOT to Back Up

  • /var/lib/docker (use volume backups instead)
  • System packages (reinstall from apt)
  • Temporary files, caches, logs
  • node_modules, .venv, build artifacts

Step 4: Create a Backup Script

Create /usr/local/bin/backup.sh:

#!/bin/bash
set -euo pipefail

# Configuration
export RESTIC_REPOSITORY="/mnt/backups/restic-repo"
export RESTIC_PASSWORD_FILE="/root/.restic-password"
BACKUP_PATHS=(
  "/home"
  "/var/www"
  "/opt/docker"
  "/etc/nginx"
  "/etc/caddy"
)
EXCLUDE_PATTERNS=(
  "node_modules"
  ".cache"
  "*.tmp"
  "*.log"
  "__pycache__"
  ".venv"
)
LOG="/var/log/restic-backup.log"

# Build exclude args
EXCLUDES=""
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
  EXCLUDES="$EXCLUDES --exclude=$pattern"
done

echo "$(date): Starting backup..." >> "$LOG"

# Stop databases before backup (optional, for consistency)
# docker stop postgres redis 2>/dev/null || true

# Run backup
restic backup ${BACKUP_PATHS[@]} $EXCLUDES \
  --verbose >> "$LOG" 2>&1

# Restart databases
# docker start postgres redis 2>/dev/null || true

# Apply retention policy
restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune >> "$LOG" 2>&1

echo "$(date): Backup complete" >> "$LOG"

# Check repository integrity (weekly)
if [ "$(date +%u)" -eq 7 ]; then
  echo "$(date): Running integrity check..." >> "$LOG"
  restic check >> "$LOG" 2>&1
fi
# Store password securely
echo "your-strong-password" > /root/.restic-password
chmod 600 /root/.restic-password

# Make script executable
chmod +x /usr/local/bin/backup.sh

Step 5: Install and Configure Rclone

# Install
curl https://rclone.org/install.sh | sudo bash

# Configure cloud storage
rclone config

Backblaze B2 Setup (Cheapest Option)

  1. Create a Backblaze B2 account (free)
  2. Create a bucket called my-server-backups
  3. Create an application key with access to that bucket
  4. In rclone config:
    NSAKatcemocyero::augnybeto2::urby-2oauprp-laicccaotuinotn--ikdey

Other Cloud Options

ProviderCost/GB/monthRclone Name
Backblaze B2$0.005b2
Wasabi$0.007s3
AWS S3$0.023s3
Google DriveFree (15GB)drive
Cloudflare R2$0.015 (free egress)s3

Step 6: Add Cloud Sync to Backup Script

Add this to the end of /usr/local/bin/backup.sh:

# Sync to cloud
echo "$(date): Syncing to cloud..." >> "$LOG"
rclone sync /mnt/backups/restic-repo b2:my-server-backups/restic \
  --transfers 4 \
  --fast-list \
  --log-file="$LOG" \
  --log-level INFO

echo "$(date): Cloud sync complete" >> "$LOG"

Step 7: Schedule with Cron

sudo crontab -e

Add:

#0#0D3M4aoin1ltyhlbyac/brkuaeuscsprkt/uialpctocv-3aerlrA/i/Mbfmiinnct/a/btbaiacocknkuupp.ss/hrestic-repocheck-read-data-subset=10%var/log/restic-backup.log2>&1

Step 8: Docker Volume Backups

For Docker services, back up volumes properly:

#!/bin/bash
# docker-backup.sh - Run BEFORE main restic backup

BACKUP_DIR="/opt/docker-backups"
mkdir -p "$BACKUP_DIR"

# PostgreSQL
docker exec postgres pg_dumpall -U postgres > "$BACKUP_DIR/postgres.sql"

# MySQL/MariaDB
docker exec mariadb mysqldump --all-databases -u root -p"$MYSQL_ROOT_PASSWORD" > "$BACKUP_DIR/mysql.sql"

# Redis
docker exec redis redis-cli BGSAVE
sleep 2
docker cp redis:/data/dump.rdb "$BACKUP_DIR/redis.rdb"

# Generic volume backup
for vol in $(docker volume ls -q); do
  docker run --rm -v "$vol:/data" -v "$BACKUP_DIR:/backup" \
    alpine tar czf "/backup/vol-${vol}.tar.gz" -C /data .
done

Add to cron to run before the main backup:

50523//uussrr//llooccaall//bbiinn//dboacckkeurp-.bsahckup.sh

Step 9: Test Your Restores

A backup you haven’t tested is not a backup.

List snapshots

restic -r /mnt/backups/restic-repo snapshots

Restore a single file

restic -r /mnt/backups/restic-repo restore latest \
  --target /tmp/restore \
  --include "/home/user/documents/important.pdf"

Restore everything

restic -r /mnt/backups/restic-repo restore latest \
  --target /tmp/full-restore

Mount snapshots (browse like a filesystem)

mkdir /mnt/restic-mount
restic -r /mnt/backups/restic-repo mount /mnt/restic-mount
# Browse /mnt/restic-mount/snapshots/latest/

Step 10: Monitoring and Alerts

Add notification to your backup script:

# At the end of backup.sh
BACKUP_SIZE=$(restic -r "$RESTIC_REPOSITORY" stats latest --json | jq -r '.total_size')
SNAPSHOT_COUNT=$(restic -r "$RESTIC_REPOSITORY" snapshots --json | jq length)

# Discord/Slack webhook notification
curl -s -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d "{\"text\": \"✅ Backup complete: ${SNAPSHOT_COUNT} snapshots, $(numfmt --to=iec $BACKUP_SIZE) total\"}"

Troubleshooting

“repository does not exist”

  • Check the path and RESTIC_REPOSITORY env var
  • Ensure the drive is mounted: mount | grep backups

Backup is slow

  • First backup is always slow (full copy) — subsequent ones are fast
  • Exclude large unnecessary files (logs, caches, media you have elsewhere)
  • Use --read-concurrency 4 for faster reads

Cloud sync fails

  • Run rclone check to verify connectivity
  • Check cloud storage bucket permissions
  • Verify API keys haven’t expired

“wrong password”

  • Restic repositories are encrypted — you need the exact password used during init
  • Check RESTIC_PASSWORD_FILE permissions and contents

Cost Estimate

For a typical home server with 100GB of backed-up data:

ComponentCost
ResticFree
RcloneFree
Local storage (1TB drive)~$40 one-time
Backblaze B2 (100GB)$0.50/month
Total ongoing$0.50/month

Conclusion

Restic + Rclone gives you a backup system that rivals enterprise solutions — encrypted, deduplicated, versioned, and offsite — for essentially free. The hardest part is setting it up once. After that, it runs silently in the background, protecting everything you’ve built.

Don’t wait for a drive failure to wish you had backups. Set this up today. Your future self will thank you.