Self-Host Restic: Modern Encrypted Backups in 15 Minutes
Backups are the insurance policy you hope you never need — until you do. If you're running self-hosted services, databases, or critical files, having a robust backup strategy isn't optional. Restic is a fast, secure, and modern backup program that encrypts your data by default, deduplicates everything, and works with virtually any storage backend.
In this guide, we'll set up Restic on your VPS or homelab server, configure automated encrypted backups to local and remote storage, and set up retention policies so you don't drown in backup bloat.
Why Restic?
Unlike traditional backup tools that simply copy files, Restic offers:
- End-to-end encryption — your data is encrypted before it leaves your machine
- Deduplication — only unique data blocks are stored, saving massive space
- Compression — modern compression algorithms reduce backup size further
- Versioning — keep hourly, daily, weekly, and monthly snapshots
- Multiple backends — local disk, SFTP, S3, MinIO, Backblaze B2, Azure, GCS, and more
- Integrity verification — cryptographic checksums ensure your backups aren't corrupted
If you liked our Borgmatic guide, Restic is the modern alternative with broader backend support and faster performance.
Prerequisites
- A VPS or server with Docker installed
- At least 10GB free space for backups (local or remote)
- Basic familiarity with Docker and cron
- 5-10 minutes of setup time
Step 1: Install Restic
The easiest way to run Restic is via Docker. Create a dedicated backup directory:
mkdir -p ~/restic-backup/data
cd ~/restic-backup
Create a docker-compose.yml file:
version: '3.8'
services:
restic:
image: restic/restic:latest
container_name: restic
volumes:
- /path/to/your/data:/data:ro # What to backup (read-only)
- ./backups:/backups # Local backup destination
- ./config:/config # Restic config and cache
environment:
- RESTIC_PASSWORD=your-secure-password-here
- RESTIC_REPOSITORY=/backups
command: ["init"]
restart: "no"
Initialize the repository:
docker-compose run --rm restic init
You should see: created restic repository 0853d8c7 at /backups
Important: Your RESTIC_PASSWORD is the encryption key. Lose it, lose your backups. Store it in a password manager or secure vault.
Step 2: Create Your First Backup
Update the compose file to run backups instead of init:
version: '3.8'
services:
restic:
image: restic/restic:latest
container_name: restic
volumes:
- /path/to/your/data:/data:ro
- ./backups:/backups
- ./config:/config
environment:
- RESTIC_PASSWORD=your-secure-password-here
- RESTIC_REPOSITORY=/backups
command: ["backup", "/data"]
restart: "no"
Run your first backup:
docker-compose run --rm restic
Restic will scan your files, deduplicate, compress, and encrypt everything. The first backup takes the longest; subsequent backups are incremental and much faster.
Step 3: Verify Your Backups
Always test your backups. Check what snapshots exist:
docker-compose run --rm restic snapshots
Verify backup integrity:
docker-compose run --rm restic check
Test a restore to a temporary location:
docker-compose run --rm restic restore latest --target /tmp/restore-test
Browse the restored files in /tmp/restore-test to confirm everything is intact.
Step 4: Automate with Cron
Create a backup script ~/restic-backup/backup.sh:
#!/bin/bash
set -e
cd ~/restic-backup
echo "=== Starting backup: $(date) ==="
# Run backup
docker-compose run --rm restic backup /data \
--exclude-file ./excludes.txt \
--tag automated
# Apply retention policy (keep 7 daily, 4 weekly, 12 monthly)
docker-compose run --rm restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--prune
echo "=== Backup complete: $(date) ==="
Create an excludes file ~/restic-backup/excludes.txt:
*.tmp
*.log
.cache
node_modules
.git
__pycache__
*.pid
*.sock
Make the script executable and add to cron:
chmod +x ~/restic-backup/backup.sh
# Edit crontab
crontab -e
# Add daily backup at 2 AM
0 2 * * * ~/restic-backup/backup.sh >> ~/restic-backup/backup.log 2>&1
Step 5: Remote Backup to S3/MinIO
Local backups are good; remote backups are better. Restic supports S3-compatible storage out of the box. Update your compose file for MinIO or AWS S3:
version: '3.8'
services:
restic:
image: restic/restic:latest
container_name: restic
volumes:
- /path/to/your/data:/data:ro
- ./config:/config
environment:
- RESTIC_PASSWORD=your-secure-password-here
- RESTIC_REPOSITORY=s3:https://s3.amazonaws.com/your-bucket-name
- AWS_ACCESS_KEY_ID=your-access-key
- AWS_SECRET_ACCESS_KEY=your-secret-key
command: ["backup", "/data"]
restart: "no"
For self-hosted MinIO, change the repository URL:
- RESTIC_REPOSITORY=s3:http://minio.yourdomain.com:9000/your-backup-bucket
Initialize the remote repository once, then run backups as usual:
docker-compose run --rm restic init
docker-compose run --rm restic
Step 6: Mount and Browse Backups
Restic has a killer feature: mount your backups as a filesystem. This lets you browse snapshots like a regular directory:
docker-compose run --rm --cap-add SYS_ADMIN \
--device /dev/fuse \
restic mount /mnt
Now browse /mnt to see all your snapshots by date. Copy files out as needed, then unmount with umount /mnt.
Verification Checklist
- ✅ Repository initialized successfully
- ✅ First backup completes without errors
- ✅
snapshotscommand shows your backup - ✅
checkpasses integrity verification - ✅ Test restore works to
/tmp/restore-test - ✅ Cron job runs automatically (check
backup.logtomorrow) - ✅ Remote repository initialized and accessible
Next Steps
Now that you have automated encrypted backups:
- Set up monitoring — Use Uptime Kuma or Grafana to alert on backup failures
- Multiple destinations — Follow the 3-2-1 rule: 3 copies, 2 media types, 1 offsite
- Database dumps — Backup PostgreSQL/MySQL dumps before Restic runs for consistent database backups
- Compare with Borgmatic — See our Borgmatic guide for an alternative approach
Wrapping Up
Restic gives you enterprise-grade backup capabilities with minimal setup. The encryption, deduplication, and flexible storage backends make it perfect for homelabbers who want serious backups without enterprise complexity.
Your data is now encrypted, versioned, and automated. Sleep better tonight.
Questions or want a specific backend covered in detail? Drop a comment below.