← All articles
green and black computer motherboard

Restic Backup for Your Homelab: Modern Deduplication and Encryption

Storage 2026-02-15 · 6 min read restic backup deduplication encryption storage s3 disaster-recovery
By HomeLab Starter Editorial TeamHome lab enthusiasts covering hardware setup, networking, and self-hosted services for home and small office environments.

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.

Restic logo

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.

Get free weekly tips in your inbox. Subscribe to HomeLab Starter