Backup intermediate ⏱ 45 minutes

Restic + Backrest: Modern Backup Strategy for Homelabs

Deduplicating backups with beautiful web UI. Fast, encrypted, and works with any storage backend.

By homelabbing.io • 2025-12-16
#restic#backrest#backup#deduplication#encryption

Master the art of secure, encrypted, and deduplicating backups with Restic paired with Backrest’s intuitive web interface. This comprehensive guide walks you through building a bulletproof backup strategy for your homelab infrastructure.

Difficulty: Intermediate to Advanced Estimated Time: 60 minutes Last Updated: December 2025 Target Audience: Homelab administrators, data-conscious users, small IT teams


What You’ll Learn

  • Deploy Restic for fast, encrypted, deduplicating backups
  • Set up Backrest web UI for easy backup management
  • Configure backup schedules for automated protection
  • Use multiple storage backends (local, S3, SFTP, B2, Azure)
  • Implement backup verification and restore procedures
  • Optimize backup performance and storage efficiency
  • Create disaster recovery runbooks
  • Integrate with monitoring and alerting systems

Prerequisites

Required Knowledge

  • Docker and Docker Compose fundamentals
  • Linux command-line proficiency
  • Basic understanding of cron scheduling
  • File system and permissions concepts
  • Networking basics (SSH, SFTP, S3 concepts)

Required Infrastructure

  • Linux server or NAS (Ubuntu 22.04+, Debian 11+)
  • Minimum: 1 GB RAM, 2 CPU cores, 20 GB storage
  • Recommended: 4+ GB RAM, 4 cores, adequate backup storage
  • Backup destination (local disk, S3-compatible storage, SFTP server, or cloud)
  • Docker and Docker Compose installed

Pre-Deployment Checklist

  • Backup destinations identified and configured
  • Storage capacity calculated for retention policy
  • Network connectivity to backup destinations verified
  • Encryption passwords/keys generated
  • Backup schedule planned (frequency, retention)
  • Critical data to backup identified

1. Understanding Restic and Backrest

What is Restic?

Restic is a modern backup program that is fast, efficient, and secure. It creates incremental backups with strong encryption and content-based deduplication, making it ideal for homelab environments where storage efficiency matters.

Key Features:

  • Content-Addressable Storage: Deduplication at the chunk level
  • Strong Encryption: AES-256 encryption by default
  • Multiple Backends: Local, SFTP, S3, B2, Azure, Google Cloud, and more
  • Incremental Backups: Only changed data is transferred
  • Verification: Built-in backup integrity checking
  • Fast Restore: Efficient data recovery with parallel operations
  • Snapshot Management: Easy browsing and restoration of specific versions
  • Cross-Platform: Works on Linux, macOS, Windows, BSD

What is Backrest?

Backrest is a web-based UI for Restic that makes backup management accessible and visual. It provides scheduling, monitoring, and restore capabilities through an intuitive interface.

Key Features:

  • Web Interface: Manage backups from any browser
  • Backup Plans: Define automated backup schedules
  • Repository Management: Multiple Restic repositories in one UI
  • Restore UI: Browse and restore files visually
  • Notifications: Email, webhook, Discord, Slack alerts
  • Statistics: Backup size, deduplication ratios, success rates
  • Multi-User: Support for multiple users and permissions

Why Restic + Backrest?

FeatureRestic + BackrestTraditional BackupsCloud Backups
DeduplicationChunk-levelFile/block levelProvider-dependent
EncryptionEnd-to-end (local)Often in-transit onlyProvider-managed
Storage EfficiencyExcellentGoodVariable
CostStorage onlyHardware costSubscription fees
PrivacyComplete controlLocal controlProvider has access
Ease of UseExcellent (Backrest UI)CLI or complex UIsVery easy
FlexibilityAny backendLocal or networkProvider-specific

How Restic Works

Backup Architecture:

Source Data → Restic → Deduplication → Encryption → Repository
                ↓
          Chunk Creation
                ↓
          Hash Calculation
                ↓
      Deduplicate (skip existing chunks)
                ↓
          AES-256 Encrypt
                ↓
    Store in Repository (local/S3/SFTP/etc.)

Repository Structure:

repository/
├── config                  # Repository configuration
├── keys/                   # Encryption keys
├── snapshots/              # Snapshot metadata
├── index/                  # Chunk index
└── data/                   # Encrypted data chunks
    ├── 00/
    ├── 01/
    └── ...

Deduplication Example:

Backup 1: 10 GB data → 10 GB stored
Backup 2: 10 GB data (5% changed) → 500 MB added (total: 10.5 GB)
Backup 3: 10 GB data (2% changed) → 200 MB added (total: 10.7 GB)

Traditional backups would use: 30 GB
Restic uses: 10.7 GB (64% storage savings)

2. Installing Restic + Backrest

Create directory structure:

# Create Backrest directories
mkdir -p /opt/backrest/{config,data,cache,repos}
cd /opt/backrest

Create docker-compose.yml:

version: '3.8'

services:
  backrest:
    image: garethgeorge/backrest:latest
    container_name: backrest
    hostname: backrest
    restart: unless-stopped
    environment:
      - BACKREST_DATA=/data
      - BACKREST_CONFIG=/config/config.json
      - XDG_CACHE_HOME=/cache
      - TZ=America/New_York
    ports:
      - "9898:9898"
    volumes:
      # Backrest configuration
      - ./config:/config
      # Backup data and metadata
      - ./data:/data
      # Restic cache for performance
      - ./cache:/cache
      # Local backup repositories
      - ./repos:/repos
      # Source data to backup (examples)
      - /opt/docker:/backup-sources/docker:ro
      - /home:/backup-sources/home:ro
      - /etc:/backup-sources/etc:ro
      # Optional: Additional mount points
      - /mnt/storage:/backup-sources/storage:ro
    networks:
      - backrest-network
    # Run as specific user (adjust UID/GID)
    user: "1000:1000"
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 512M

networks:
  backrest-network:
    driver: bridge

Set permissions:

# Set ownership
sudo chown -R 1000:1000 /opt/backrest

# Verify permissions
ls -la /opt/backrest

Deploy the stack:

# Start Backrest
docker-compose up -d

# View logs
docker-compose logs -f backrest

# Verify status
docker-compose ps

Access the web UI:

Open your browser to http://your-server-ip:9898

On first access, you’ll be prompted to set up authentication.

Method 2: Standalone Restic Installation

For servers without Docker or maximum performance.

Install Restic:

# Download latest release
RESTIC_VERSION=$(curl -s https://api.github.com/repos/restic/restic/releases/latest | grep -oP '"tag_name": "K(.*)(?=")')
wget https://github.com/restic/restic/releases/download/${RESTIC_VERSION}/restic_${RESTIC_VERSION#v}_linux_amd64.bz2

# Extract
bzip2 -d restic_${RESTIC_VERSION#v}_linux_amd64.bz2

# Install
sudo mv restic_${RESTIC_VERSION#v}_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic

# Verify installation
restic version

Install Backrest:

# Download latest Backrest release
BACKREST_VERSION=$(curl -s https://api.github.com/repos/garethgeorge/backrest/releases/latest | grep -oP '"tag_name": "K(.*)(?=")')
wget https://github.com/garethgeorge/backrest/releases/download/${BACKREST_VERSION}/backrest_Linux_x86_64.tar.gz

# Extract
tar -xzf backrest_Linux_x86_64.tar.gz

# Install
sudo mv backrest /usr/local/bin/
sudo chmod +x /usr/local/bin/backrest

# Create directories
sudo mkdir -p /var/lib/backrest/{config,data,cache}
sudo chown -R $USER:$USER /var/lib/backrest

Create systemd service:

sudo nano /etc/systemd/system/backrest.service

Add:

[Unit]
Description=Backrest Backup Management
After=network.target

[Service]
Type=simple
User=backrest
Group=backrest
Environment="BACKREST_DATA=/var/lib/backrest/data"
Environment="BACKREST_CONFIG=/var/lib/backrest/config/config.json"
Environment="XDG_CACHE_HOME=/var/lib/backrest/cache"
ExecStart=/usr/local/bin/backrest serve
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Create service user:

sudo useradd -r -s /bin/false backrest
sudo chown -R backrest:backrest /var/lib/backrest

Enable and start service:

sudo systemctl daemon-reload
sudo systemctl enable backrest.service
sudo systemctl start backrest.service
sudo systemctl status backrest.service

3. Initial Configuration

Setting Up Your First Repository

A repository is where Restic stores encrypted backup data.

Via Backrest Web UI:

  1. Access http://your-server-ip:9898
  2. Click Add Repository
  3. Configure repository settings:
    • Repository Name: Descriptive name (e.g., “Local-NAS-Backups”)
    • Repository Type: Choose backend
    • Repository Path/URL: Location for backups
    • Password: Strong encryption password (store securely!)
  4. Click Create Repository

Repository Types:

Local Repository:

Type: Local
Path: /repos/local-backups

SFTP Repository:

Type: SFTP
Path: sftp:[email protected]:/backups/restic-repo
Password: SSH key or password

S3 Repository (AWS, MinIO, Wasabi, etc.):

Type: S3
Path: s3:s3.amazonaws.com/my-backup-bucket
AWS Access Key: YOUR_ACCESS_KEY
AWS Secret Key: YOUR_SECRET_KEY
Region: us-east-1

Backblaze B2:

Type: B2
Path: b2:my-backup-bucket:/restic-repo
Account ID: YOUR_B2_ACCOUNT_ID
Application Key: YOUR_B2_APP_KEY

Azure Blob Storage:

Type: Azure
Path: azure:container-name:/
Account Name: YOUR_AZURE_ACCOUNT
Account Key: YOUR_AZURE_KEY

Creating Your First Backup Plan

Backup plans define what to backup, when, and how to retain snapshots.

Via Backrest Web UI:

  1. Click Add Plan
  2. Configure plan settings:

Basic Settings:

  • Plan Name: Descriptive name (e.g., “Docker Containers Daily”)
  • Repository: Select created repository
  • Paths to Backup: Add directories
    /backup-sources/docker
    /backup-sources/home

Schedule:

  • Backup Schedule: Cron expression or preset
    0 2 * * *  # Daily at 2 AM
    0 2 * * 0  # Weekly on Sundays at 2 AM
    0 2 1 * *  # Monthly on the 1st at 2 AM

Retention Policy:

  • Keep Last: 7 (keep last 7 backups)
  • Keep Daily: 7 (keep 7 daily backups)
  • Keep Weekly: 4 (keep 4 weekly backups)
  • Keep Monthly: 12 (keep 12 monthly backups)
  • Keep Yearly: 3 (keep 3 yearly backups)

Exclusions:

Add patterns for files/folders to exclude:

# Temporary files
**/*.tmp
**/temp/
**/cache/

# System files
**/.DS_Store
**/Thumbs.db

# Logs (optional)
**/*.log

# Large media caches
**/plex/Cache/
**/jellyfin/cache/

# Docker volumes (if backing up separately)
**/docker/volumes/

Advanced Options:

  • Backup Tags: Add tags for organization
  • Environment Variables: Pass variables to Restic
  • Hooks: Run scripts before/after backup
  1. Click Save Plan

Manual test run:

Click Run Now to execute the backup immediately and verify configuration.


4. Storage Backend Configuration

Local Storage

Advantages:

  • Fast backup and restore
  • No cloud costs
  • Complete privacy
  • No bandwidth limitations

Disadvantages:

  • Single point of failure
  • No off-site protection
  • Vulnerable to local disasters

Setup:

# Create repository directory
mkdir -p /mnt/backup-drive/restic-repo

# Initialize repository (via Backrest or CLI)
# CLI method:
export RESTIC_REPOSITORY="/mnt/backup-drive/restic-repo"
export RESTIC_PASSWORD="your-secure-password"
restic init

# Verify
restic snapshots

Best practices:

  • Use dedicated backup drive separate from source data
  • Consider RAID for redundancy
  • Implement monitoring for drive health
  • Combine with off-site backups

SFTP (Remote Server)

Advantages:

  • Off-site protection
  • Encrypted transfer
  • Uses existing SSH infrastructure
  • Flexible storage options

Setup:

On backup server:

# Create dedicated backup user
sudo useradd -m -s /bin/bash backup-user

# Create SSH directory
sudo mkdir -p /home/backup-user/.ssh
sudo chown backup-user:backup-user /home/backup-user/.ssh
sudo chmod 700 /home/backup-user/.ssh

# Create backup directory
sudo mkdir -p /backups/restic-repo
sudo chown backup-user:backup-user /backups/restic-repo

On source server:

# Generate SSH key (if not exists)
ssh-keygen -t ed25519 -C "restic-backup"

# Copy public key to backup server
ssh-copy-id [email protected]

# Test connection
ssh [email protected]

Configure in Backrest:

Repository Type: SFTP
Path: sftp:[email protected]:/backups/restic-repo
SSH Key: /root/.ssh/id_ed25519 (or configured key)

Initialize repository:

export RESTIC_REPOSITORY="sftp:[email protected]:/backups/restic-repo"
export RESTIC_PASSWORD="your-secure-password"
restic init

S3-Compatible Storage

Works with AWS S3, MinIO, Wasabi, Backblaze B2 (via S3-compatible API), and others.

AWS S3 Setup:

Create S3 bucket:

# Using AWS CLI
aws s3 mb s3://my-restic-backups --region us-east-1

# Set lifecycle policy (optional - for automatic deletion)
aws s3api put-bucket-lifecycle-configuration   --bucket my-restic-backups   --lifecycle-configuration file://lifecycle-policy.json

lifecycle-policy.json:

{
  "Rules": [
    {
      "Id": "DeleteOldBackups",
      "Status": "Enabled",
      "Filter": {},
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 90
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}

Create IAM user with S3 permissions:

IAM policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": "arn:aws:s3:::my-restic-backups"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload"
      ],
      "Resource": "arn:aws:s3:::my-restic-backups/*"
    }
  ]
}

Configure in Backrest:

Repository Type: S3
Path: s3:s3.amazonaws.com/my-restic-backups
AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Region: us-east-1

MinIO Setup:

If self-hosting S3-compatible storage:

# docker-compose.yml for MinIO
services:
  minio:
    image: minio/minio:latest
    container_name: minio
    restart: unless-stopped
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: your-secure-password
    volumes:
      - ./minio-data:/data
    command: server /data --console-address ":9001"

Configure Restic for MinIO:

export RESTIC_REPOSITORY="s3:http://minio-server:9000/restic-backups"
export AWS_ACCESS_KEY_ID="admin"
export AWS_SECRET_ACCESS_KEY="your-secure-password"
restic init

Backblaze B2

Create B2 bucket:

  1. Log into Backblaze B2 console
  2. Create new bucket: “restic-backups”
  3. Create application key with access to this bucket
  4. Note Account ID and Application Key

Configure in Backrest:

Repository Type: B2
Path: b2:restic-backups:/
Account ID: YOUR_ACCOUNT_ID
Application Key: YOUR_APPLICATION_KEY

Cost optimization:

B2 pricing (as of 2025):

  • Storage: $0.005/GB/month
  • Download: $0.01/GB (first 3x storage free)
  • API calls: Mostly free

For 500 GB backups:

  • Monthly cost: ~$2.50
  • Very cost-effective for homelab backups

5. Backup Plans and Scheduling

Designing Retention Policies

The 3-2-1 Rule:

  • 3 copies of data (original + 2 backups)
  • 2 different media types
  • 1 off-site copy

Common retention strategies:

Minimal (space-constrained):

Keep Last: 3
Keep Daily: 7
Keep Weekly: 0
Keep Monthly: 0
Keep Yearly: 0

Total snapshots: ~10
Storage efficiency: Excellent
Recovery flexibility: Limited

Balanced (recommended for homelabs):

Keep Last: 7
Keep Daily: 7
Keep Weekly: 4
Keep Monthly: 12
Keep Yearly: 3

Total snapshots: ~30
Storage efficiency: Good
Recovery flexibility: Excellent

Paranoid (critical data):

Keep Last: 14
Keep Daily: 14
Keep Weekly: 8
Keep Monthly: 24
Keep Yearly: 7

Total snapshots: ~50
Storage efficiency: Moderate
Recovery flexibility: Maximum

Scheduling Best Practices

Avoid peak usage times:

# Good - night backups for home servers
0 2 * * *  # 2 AM daily

# Bad - peak evening hours
0 20 * * *  # 8 PM daily

Stagger multiple plans:

Plan 1 (Docker containers): 0 2 * * *  # 2 AM
Plan 2 (User data): 0 3 * * *          # 3 AM
Plan 3 (Databases): 0 4 * * *          # 4 AM

Consider bandwidth:

For limited connections or cloud backups:

# Weekend backups for large datasets
0 2 * * 6  # Saturdays at 2 AM

Pre/Post Backup Hooks

Execute scripts before or after backups.

Pre-backup hook (database dump):

#!/bin/bash
# /opt/scripts/pre-backup-db.sh

# Dump PostgreSQL databases
docker exec postgres pg_dumpall -U postgres > /backup-sources/db-dumps/postgres-all.sql

# Dump MySQL databases
docker exec mysql mysqldump --all-databases -uroot -p${MYSQL_ROOT_PASSWORD} > /backup-sources/db-dumps/mysql-all.sql

# Create timestamp
date > /backup-sources/db-dumps/backup-timestamp.txt

Post-backup hook (notification):

#!/bin/bash
# /opt/scripts/post-backup-notify.sh

# Send notification via Discord webhook
WEBHOOK_URL="https://discord.com/api/webhooks/..."
MESSAGE="Backup completed successfully at $(date)"

curl -H "Content-Type: application/json"   -d "{"content": "$MESSAGE"}"   "$WEBHOOK_URL"

Configure in Backrest:

In plan settings:

Hooks → Pre-backup Command: /opt/scripts/pre-backup-db.sh
Hooks → Post-backup Command: /opt/scripts/post-backup-notify.sh

6. Restore Procedures

Browsing Snapshots

Via Backrest Web UI:

  1. Go to Repositories → [Your Repository]
  2. Click Snapshots tab
  3. Browse available snapshots by date
  4. Click a snapshot to view contents

Via Restic CLI:

# Set environment
export RESTIC_REPOSITORY="/repos/local-backups"
export RESTIC_PASSWORD="your-password"

# List all snapshots
restic snapshots

# List snapshots for specific path
restic snapshots --path /backup-sources/docker

# View snapshot contents
restic ls latest
restic ls snapshot-id

# Search for specific file
restic find filename.txt

Restoring Files

Method 1: Via Backrest Web UI

  1. Go to snapshot
  2. Navigate to file/folder
  3. Click Restore
  4. Choose destination
  5. Click Confirm

Method 2: Via Restic CLI (full restore)

# Restore latest snapshot to original location
restic restore latest --target /

# Restore latest snapshot to alternate location
restic restore latest --target /mnt/restore

# Restore specific snapshot
restic restore abc123def --target /mnt/restore

# Restore specific path only
restic restore latest --target /mnt/restore --path /backup-sources/docker

Method 3: Mount snapshot as filesystem (read-only)

# Create mount point
mkdir -p /mnt/restic-mount

# Mount latest snapshot
restic mount /mnt/restic-mount

# Browse files
cd /mnt/restic-mount
ls -la

# Copy files manually
cp -a /mnt/restic-mount/snapshots/latest/backup-sources/docker/important-file.txt /restore/

# Unmount when done
fusermount -u /mnt/restic-mount
# Or: umount /mnt/restic-mount

Disaster Recovery Scenario

Complete system failure:

Step 1: Prepare new system

# Install Restic
wget https://github.com/restic/restic/releases/latest/download/restic_*_linux_amd64.bz2
bzip2 -d restic_*_linux_amd64.bz2
sudo mv restic_*_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic

Step 2: Configure repository access

# Set repository (adjust for your backend)
export RESTIC_REPOSITORY="sftp:backup-user@backup-server:/backups/restic-repo"
export RESTIC_PASSWORD="your-password"

# Or for S3:
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backups"
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
export RESTIC_PASSWORD="your-password"

Step 3: Verify repository access

# List snapshots
restic snapshots

# If successful, repository is accessible

Step 4: Restore data

# Restore to root (careful!)
restic restore latest --target /

# Or restore to temporary location first
mkdir -p /mnt/restore
restic restore latest --target /mnt/restore

# Verify contents
ls -la /mnt/restore

# Move to correct locations
rsync -av /mnt/restore/ /

Step 5: Verify and restart services

# For Docker-based homelab
cd /opt/docker
docker-compose up -d

# Verify services
docker ps

7. Performance Optimization

Restic Cache Tuning

Restic uses a local cache to speed up operations.

Cache location:

# Default cache location
~/.cache/restic/

# For Docker
/cache/restic/

Cache size management:

# Check cache size
du -sh ~/.cache/restic/

# Limit cache size (via environment variable)
export RESTIC_CACHE_MAX_SIZE=2048  # 2 GB limit

# Clear cache (forces rebuild on next operation)
restic cache --cleanup

Backup Performance Tuning

Increase parallelism:

# Use more CPU cores for compression
restic backup /data --pack-size 128

# Increase file read concurrency
restic backup /data --read-concurrency 4

Adjust compression level:

# Lower compression (faster, larger backups)
restic backup /data --compression off

# Maximum compression (slower, smaller backups)
restic backup /data --compression max

Large file optimization:

# Increase pack size for large files
restic backup /data --pack-size 256

In Backrest UI:

Plan → Advanced Options → Environment Variables:

RESTIC_PACK_SIZE=128
RESTIC_READ_CONCURRENCY=4
RESTIC_COMPRESSION=auto

Network Optimization (S3/SFTP)

For slow connections:

# Limit bandwidth (in KiB/s)
restic backup /data --limit-upload 1024  # 1 MB/s
restic backup /data --limit-download 2048  # 2 MB/s

For fast connections:

# Increase parallelism
export RESTIC_S3_CONNECTIONS=10  # More concurrent S3 uploads

Repository Maintenance

Prune old snapshots:

Done automatically by retention policies, but can be run manually:

# Prune according to policy
restic forget --keep-last 7 --keep-daily 7 --keep-weekly 4 --prune

# Check what would be removed (dry-run)
restic forget --keep-last 7 --keep-daily 7 --keep-weekly 4 --dry-run

Optimize repository (rebuild index):

# Rebuild index for better performance
restic rebuild-index

# Remove orphaned data
restic prune

# Check repository integrity
restic check

# Deep check (slower but thorough)
restic check --read-data

Scheduled maintenance:

# Create maintenance script
# /opt/scripts/restic-maintenance.sh

#!/bin/bash
export RESTIC_REPOSITORY="/repos/local-backups"
export RESTIC_PASSWORD="your-password"

# Rebuild index
echo "Rebuilding index..."
restic rebuild-index

# Prune orphaned data
echo "Pruning repository..."
restic prune

# Integrity check
echo "Checking repository..."
restic check

echo "Maintenance complete at $(date)"

Automate with cron:

# Weekly maintenance on Sundays at 3 AM
0 3 * * 0 /opt/scripts/restic-maintenance.sh >> /var/log/restic-maintenance.log 2>&1

8. Monitoring and Alerting

Backup Success Monitoring

Via Backrest:

Backrest provides built-in notifications.

Configure notifications:

  1. Settings → Notifications
  2. Choose notification type:
    • Email (SMTP)
    • Discord webhook
    • Slack webhook
    • Gotify
    • Generic webhook

Email (SMTP) configuration:

SMTP Server: smtp.gmail.com
SMTP Port: 587
SMTP Username: [email protected]
SMTP Password: app-specific-password
From Address: [email protected]
To Address: [email protected]

Notification triggers:

☑ Backup success
☑ Backup failure
☑ Prune success
☑ Prune failure
☐ Check success (optional)
☑ Check failure

Healthcheck Integration

Healthchecks.io integration:

# Create healthcheck script
# /opt/scripts/backup-healthcheck.sh

#!/bin/bash
HEALTHCHECK_URL="https://hc-ping.com/your-uuid-here"

# Run backup
if restic backup /data; then
    # Success - ping healthcheck
    curl -fsS --retry 3 "$HEALTHCHECK_URL" > /dev/null
else
    # Failure - ping with /fail
    curl -fsS --retry 3 "$HEALTHCHECK_URL/fail" > /dev/null
fi

Prometheus Metrics

Export Restic metrics for Prometheus monitoring.

Using restic-exporter:

# docker-compose.yml
services:
  restic-exporter:
    image: ngosang/restic-exporter:latest
    container_name: restic-exporter
    restart: unless-stopped
    environment:
      - RESTIC_REPOSITORY=/repos/local-backups
      - RESTIC_PASSWORD=your-password
      - REFRESH_INTERVAL=3600  # 1 hour
    ports:
      - "8001:8001"
    volumes:
      - ./repos:/repos:ro
      - ./cache:/cache

Prometheus scrape config:

# prometheus.yml
scrape_configs:
  - job_name: 'restic'
    static_configs:
      - targets: ['restic-exporter:8001']

Example Grafana dashboard queries:

# Last backup age (hours)
(time() - restic_last_backup_timestamp) / 3600

# Repository size (GB)
restic_repository_size_bytes / 1024 / 1024 / 1024

# Number of snapshots
restic_snapshots_total

# Backup success rate (last 7 days)
rate(restic_backup_success_total[7d])

9. Security Best Practices

Encryption Key Management

Password storage:

Bad:

# Hardcoded in scripts
export RESTIC_PASSWORD="mypassword123"

Good:

# Use password file
echo "your-secure-password" > /root/.restic-password
chmod 600 /root/.restic-password
export RESTIC_PASSWORD_FILE=/root/.restic-password

Better:

# Use password manager or secrets vault
# Hashicorp Vault example:
export RESTIC_PASSWORD=$(vault kv get -field=password secret/restic)

Best:

# Hardware security key (YubiKey) for encryption
# Requires restic compiled with support

Repository Security

Limit repository access:

# Filesystem permissions (local)
chmod 700 /repos/restic-repo
chown backupuser:backupuser /repos/restic-repo

# SSH restrictions (SFTP)
# In ~/.ssh/authorized_keys on backup server:
command="rsync --server --daemon .",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...

S3 bucket policies:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:DeleteBucket",
      "Resource": "arn:aws:s3:::my-restic-backups"
    },
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutBucketPolicy",
      "Resource": "arn:aws:s3:::my-restic-backups"
    }
  ]
}

Immutable Backups

Protect against ransomware by making backups immutable.

S3 Object Lock:

# Enable versioning
aws s3api put-bucket-versioning   --bucket my-restic-backups   --versioning-configuration Status=Enabled

# Enable object lock (must be set at bucket creation)
# Or use lifecycle policies for retention

Append-only mode (for SFTP):

# Create append-only repository
restic init --repository-version 2

# On backup server, use append-only SSH key
# In authorized_keys:
command="restic-server --append-only --path /backups/restic-repo" ssh-ed25519 AAAA...

10. Troubleshooting

Issue 1: Backup Failing with “Repository Locked”

Cause: Previous backup crashed, leaving lock file.

Solution:

# Check locks
restic list locks

# Remove stale locks (only if no backup is running!)
restic unlock

# Verify and retry
restic backup /data

Issue 2: Slow Backups

Diagnosis:

# Run backup with verbose output
restic backup /data --verbose

# Check which files are slow
restic backup /data --verbose=2

Solutions:

  1. Increase cache size
  2. Use faster storage for cache
  3. Exclude large, frequently-changing files
  4. Increase network bandwidth (for remote repos)
  5. Use SSD for source data if possible

Issue 3: Out of Space on Repository

Diagnosis:

# Check repository statistics
restic stats

# Find large snapshots
restic snapshots --compact

Solutions:

# Prune old snapshots aggressively
restic forget --keep-last 3 --keep-daily 7 --prune

# Remove unreferenced data
restic prune --max-unused 0

Issue 4: Restore Verification

Always verify restores:

# Restore to temporary location
restic restore latest --target /tmp/restore-test

# Compare with original (if still available)
diff -r /original-data /tmp/restore-test

# Or verify specific files
sha256sum /original-data/important-file
sha256sum /tmp/restore-test/important-file

Conclusion

You now have a comprehensive Restic + Backrest backup solution for your homelab.

Key Takeaways:

  1. Encryption: All backups encrypted end-to-end with AES-256
  2. Deduplication: Massive storage savings through chunk-level dedup
  3. Flexibility: Multiple backends, local and cloud options
  4. Reliability: Verified backups, automated retention, integrity checking
  5. Usability: Backrest UI makes complex operations simple

Your Next Steps:

  • Test restore procedures quarterly
  • Document your backup configuration
  • Set up monitoring and alerting
  • Implement off-site backups (3-2-1 rule)
  • Create disaster recovery runbook
  • Verify backups actually work (test restores!)

Related Guides:

  • Borg Backup + Vorta: Efficient Homelab Backups (alternative solution)
  • MinIO: Self-Hosted S3-Compatible Object Storage (backup backend)
  • Syncthing: Peer-to-Peer File Synchronization (complement to backups)

Your data is now protected with enterprise-grade backup technology!


Guide Version: 1.0 Last Updated: December 2025 Estimated Read Time: 40-50 minutes Estimated Implementation Time: 60 minutes + testing

Created for homelabbing.io - AI-Forward Homelab Resource Platform