Restic + Backrest: Modern Backup Strategy for Homelabs
Deduplicating backups with beautiful web UI. Fast, encrypted, and works with any storage backend.
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?
| Feature | Restic + Backrest | Traditional Backups | Cloud Backups |
|---|---|---|---|
| Deduplication | Chunk-level | File/block level | Provider-dependent |
| Encryption | End-to-end (local) | Often in-transit only | Provider-managed |
| Storage Efficiency | Excellent | Good | Variable |
| Cost | Storage only | Hardware cost | Subscription fees |
| Privacy | Complete control | Local control | Provider has access |
| Ease of Use | Excellent (Backrest UI) | CLI or complex UIs | Very easy |
| Flexibility | Any backend | Local or network | Provider-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
Method 1: Docker Deployment (Recommended)
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:
- Access
http://your-server-ip:9898 - Click Add Repository
- 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!)
- 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:
- Click Add Plan
- 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
- 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:
- Log into Backblaze B2 console
- Create new bucket: “restic-backups”
- Create application key with access to this bucket
- 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:
- Go to Repositories → [Your Repository]
- Click Snapshots tab
- Browse available snapshots by date
- 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
- Go to snapshot
- Navigate to file/folder
- Click Restore
- Choose destination
- 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:
- Settings → Notifications
- 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:
- Increase cache size
- Use faster storage for cache
- Exclude large, frequently-changing files
- Increase network bandwidth (for remote repos)
- 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:
- Encryption: All backups encrypted end-to-end with AES-256
- Deduplication: Massive storage savings through chunk-level dedup
- Flexibility: Multiple backends, local and cloud options
- Reliability: Verified backups, automated retention, integrity checking
- 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