Restic Backup for Your Homelab: Modern Deduplication and Encryption
Restic is a fast, secure backup program that handles deduplication, encryption, and multiple storage backends in a single binary. It's written in Go, which means no runtime dependencies — download one binary and you're ready to go. For homelabs, Restic is particularly attractive because it can back up to nearly anywhere: a local drive, an NFS share, an SFTP server, S3-compatible object storage (MinIO, Backblaze B2, Wasabi), or even a REST server designed specifically for Restic.
Photo by Shoeib Abolhassani on Unsplash
Where BorgBackup is the established veteran of deduplicated backups, Restic is the newer alternative that prioritizes simplicity and backend flexibility. Both are excellent tools, and which one you pick depends on your priorities. This guide covers Restic from installation through a fully automated backup system, and ends with an honest comparison against Borg so you can make that call.

Installing Restic
Restic ships as a single static binary. You can install it from your package manager or grab the latest release directly.
# Debian/Ubuntu
sudo apt update
sudo apt install -y restic
# Fedora
sudo dnf install -y restic
# Latest binary (recommended — distro packages lag behind)
wget https://github.com/restic/restic/releases/download/v0.17.3/restic_0.17.3_linux_amd64.bz2
bunzip2 restic_0.17.3_linux_amd64.bz2
sudo mv restic_0.17.3_linux_amd64 /usr/local/bin/restic
sudo chmod +x /usr/local/bin/restic
# Verify
restic version
If you installed from your package manager, consider updating Restic itself periodically:
sudo restic self-update
Initializing a Repository
A Restic repository is where your backup data lives. You initialize it once per storage location, and Restic handles all the internal structure (data chunks, indexes, snapshots, locks).
Local or NFS Backend
The simplest option — back up to a local drive, NAS mount, or USB disk:
restic init --repo /mnt/backup/restic-homelab
Restic will prompt for a password. This encrypts the entire repository — every chunk of data, every file name, every metadata entry. Without this password, the backup data is unreadable. Store it in your password manager and write it down somewhere physical.
SFTP Backend
Back up to any machine you can SSH into:
restic init --repo sftp:backup-server:/data/restic-homelab
Set up SSH key authentication first to enable unattended backups:
ssh-keygen -t ed25519 -f ~/.ssh/restic_backup -N ""
ssh-copy-id -i ~/.ssh/restic_backup.pub user@backup-server
Add an SSH config entry to simplify the command:
# ~/.ssh/config
Host backup-server
HostName 192.168.1.50
User backupuser
IdentityFile ~/.ssh/restic_backup
S3-Compatible Backend (MinIO, Backblaze B2, Wasabi)
This is where Restic really stands apart from Borg. Native S3 support means you can use any S3-compatible storage:
# MinIO (self-hosted)
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin
restic init --repo s3:http://minio.homelab.local:9000/restic-backups
# Backblaze B2 (via S3-compatible API)
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-app-key
restic init --repo s3:s3.us-west-002.backblazeb2.com/your-bucket-name
# Wasabi
export AWS_ACCESS_KEY_ID=your-key
export AWS_SECRET_ACCESS_KEY=your-secret
restic init --repo s3:s3.wasabisys.com/your-bucket
REST Server Backend
Restic has a companion REST server (rest-server) that provides a purpose-built backend with optional authentication and append-only mode:
# On the server
docker run -p 8000:8000 -v /data/restic:/data restic/rest-server --append-only
# On the client
restic init --repo rest:http://backup-server:8000/homelab
Append-only mode is a killer feature for ransomware protection — the backup client can create new snapshots but can never delete old ones.
Creating Backups
The basic backup command:
restic -r /mnt/backup/restic-homelab backup /etc /home /var/lib/docker/volumes
Restic scans the specified paths, splits files into content-defined chunks, deduplicates against existing data in the repository, compresses and encrypts the new chunks, and creates a snapshot referencing all the data.
Useful Backup Options
# Tag snapshots for easy filtering later
restic backup --tag homeserver --tag daily /etc /home
# Exclude patterns
restic backup --exclude="*.tmp" --exclude-caches /home
# Use an exclude file
restic backup --exclude-file=/etc/restic-excludes.txt /
# Read files from a list
restic backup --files-from=/etc/restic-includes.txt
# Limit bandwidth (useful for offsite backups)
restic backup --limit-upload 5000 /home # 5 MB/s
A practical exclude file for a full-system backup:
# /etc/restic-excludes.txt
/proc
/sys
/dev
/run
/tmp
/var/tmp
/var/cache
/swapfile
/var/lib/docker/overlay2
*.swap
*.tmp
lost+found
Backing Up Docker Volumes
For Docker-based homelabs, backing up volumes is critical:
# Back up named volumes
restic backup /var/lib/docker/volumes/
# Or back up bind mounts from your compose directory
restic backup /opt/docker/
For databases, take a dump first rather than backing up raw data files:
# PostgreSQL
pg_dumpall -U postgres > /tmp/pg_backup.sql
restic backup /tmp/pg_backup.sql --tag database
rm /tmp/pg_backup.sql
Like what you're reading? Subscribe to HomeLab Starter — free weekly guides in your inbox.
Managing Snapshots
List all snapshots:
restic -r /mnt/backup/restic-homelab snapshots
Output looks like this:
ID Time Host Tags Paths
────────────────────────────────────────────────────────────
a1b2c3d4 2026-02-14 02:00:05 homeserver daily /etc, /home
e5f6g7h8 2026-02-15 02:00:04 homeserver daily /etc, /home
Filter by tag or host:
restic snapshots --tag database
restic snapshots --host homeserver
Compare two snapshots to see what changed:
restic diff a1b2c3d4 e5f6g7h8
Restoring Data
Restore an entire snapshot:
restic -r /mnt/backup/restic-homelab restore latest --target /tmp/restore
Restore specific files or directories:
# Restore a single file
restic restore latest --target /tmp/restore --include /etc/nginx/nginx.conf
# Restore a directory
restic restore latest --target /tmp/restore --include /home/user/documents
# Restore from a specific snapshot
restic restore a1b2c3d4 --target /tmp/restore
Mount a snapshot as a FUSE filesystem for interactive browsing:
mkdir /mnt/restic-mount
restic -r /mnt/backup/restic-homelab mount /mnt/restic-mount
# Browse like a normal filesystem
ls /mnt/restic-mount/snapshots/latest/etc/
cp /mnt/restic-mount/snapshots/latest/etc/nginx/nginx.conf /etc/nginx/
# Unmount when done
fusermount -u /mnt/restic-mount
The FUSE mount is one of Restic's best features for recovery — you can browse through all your snapshots and cherry-pick exactly the files you need without extracting everything.
Pruning and Retention Policies
Without pruning, your repository grows forever. The forget command marks snapshots for removal based on your retention policy, and prune actually reclaims the space:
# Keep 7 daily, 4 weekly, 6 monthly, 2 yearly snapshots
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --keep-yearly 2 --prune
# Dry run first to see what would be removed
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run
You can also group by host and tags so different machines have independent retention:
restic forget --group-by host,tags --keep-daily 7 --keep-weekly 4 --prune
Automating with systemd
Create a backup script, then use systemd timers for scheduling. This approach is more reliable than cron — it handles missed runs, provides logging through journald, and shows status in systemctl.
Backup Script
#!/bin/bash
# /usr/local/bin/restic-backup.sh
set -euo pipefail
export RESTIC_REPOSITORY="/mnt/backup/restic-homelab"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
# Run backup
restic backup \
--exclude-file=/etc/restic/excludes.txt \
--tag "$(hostname)" \
--tag daily \
/etc /home /var/lib/docker/volumes /opt/docker
# Prune old snapshots
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--keep-yearly 2 \
--prune
# Verify repository integrity (weekly)
if [ "$(date +%u)" -eq 7 ]; then
restic check
fi
sudo chmod +x /usr/local/bin/restic-backup.sh
echo "your-repo-password" | sudo tee /etc/restic/password
sudo chmod 600 /etc/restic/password
systemd Service and Timer
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic backup
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
Nice=19
IOSchedulingClass=idle
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run Restic backup daily at 2 AM
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=30min
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
# Check timer status
systemctl list-timers restic-backup.timer
Monitoring Backup Health
Restic doesn't have built-in monitoring, but it's straightforward to add. After each backup, write a status file or send a notification:
# Append to the backup script
if restic backup ... ; then
curl -s "https://ntfy.homelab.local/backups" \
-d "Restic backup completed successfully on $(hostname)"
else
curl -s "https://ntfy.homelab.local/backups" \
-H "Priority: high" \
-d "FAILED: Restic backup on $(hostname)"
fi
Check repository integrity regularly:
# Quick check (metadata only)
restic check
# Full check (verifies all data blobs — slow but thorough)
restic check --read-data
Restic vs. BorgBackup
Both are excellent deduplicated backup tools. Here's how they compare for homelab use:
| Feature | Restic | BorgBackup |
|---|---|---|
| Language | Go (single binary) | Python + C |
| Encryption | AES-256 (always on) | AES-256 (optional) |
| Deduplication | Content-defined chunking | Content-defined chunking |
| Compression | zstd (since v0.14) | lz4, zstd, zlib |
| S3 backend | Native | Not supported |
| SFTP backend | Yes | Yes |
| REST backend | Yes (rest-server) | No |
| FUSE mount | Yes | Yes |
| Append-only mode | Yes (rest-server) | Yes (server-side) |
| Speed | Faster on large repos | Faster initial backup |
| Maturity | Since 2015 | Since 2015 (attic fork) |
| Automation wrapper | runrestic, autorestic | borgmatic |
Choose Restic if you need S3/cloud backends, prefer a single binary with no dependencies, or want to back up multiple machines to a central REST server with append-only protection.
Choose Borg if you want maximum compression ratios, your backups are always to SSH-reachable servers, or you're already invested in the borgmatic ecosystem.
Both tools support the 3-2-1 backup strategy. Many homelab operators actually run both — Borg for local NAS backups (where its superior compression saves disk space) and Restic for offsite cloud backups (where its native S3 support is unmatched).
Next Steps
Once your Restic backups are running, test your restores. A backup you've never restored from is a backup you can't trust. Schedule a quarterly restore test where you spin up a VM and recover from scratch. Also explore Restic's copy command for copying snapshots between repositories — this is perfect for maintaining a local and offsite copy of the same backup chain without running the backup twice.
