Why You Need Automated Backups
You’re running one or more VPS instances hosting websites, databases, configs, and user data. If your disk fails, your provider has an outage, or you accidentally delete something critical — where does your data go?
Most VPS users rely solely on their provider’s snapshot feature, but this isn’t enough:
- Snapshots are usually in the same datacenter — useless if the facility goes down
- Snapshot pricing scales poorly and retention is limited
- Your data sits on someone else’s infrastructure with zero privacy guarantees
- No cross-server or cross-region replication
Restic is a powerful open-source backup tool featuring incremental snapshots, end-to-end encryption, and deduplication. Paired with S3-compatible object storage (MinIO, Backblaze B2, Aliyun OSS), you can build an enterprise-grade, low-cost, fully self-controlled backup system.
Feature Comparison
| Feature | Restic + S3 | Provider Snapshots | Commercial Backup Services |
|---|---|---|---|
| Incremental backups | ✅ Automatic dedup | ❌ Full copy each time | ✅ |
| End-to-end encryption | ✅ Client-side AES-256 | ❌ | ⚠️ Partial |
| Cross-region disaster recovery | ✅ Replicate anywhere | ❌ | ⚠️ Limited |
| Monthly cost (100GB) | ~$3-5 | $15-60 | $20-80 |
| Data ownership | Fully private | Provider-controlled | Third-party |
| Restore granularity | File-level precise | Full VM only | File/VM |
Architecture Overview
┌──────────────────────────────────────────────────────────────────┐
│ Your VPS (Backup Source) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ App Data │ │ Database │ │ System Config │ │
│ │ /var/www/ │ │ /var/lib/ │ │ /etc/ │ │
│ │ /home/ │ │ docker/ │ │ crontab │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └───────────────────┼─────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Restic Backup Client │ │
│ │ • Incremental • Encrypted • Deduped │
│ └───────────┬─────────────┘ │
└───────────────────────────┼────────────────────────────────────────┘
│ HTTPS (encrypted in transit)
▼
┌──────────────────────────────────────────────────────────────────┐
│ S3-Compatible Object Storage │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Backup Repository │ │
│ │ • Encrypted blocks (AES-256-GCM) │ │
│ │ • Fixed-size chunks (4MB), native dedup │ │
│ │ │ • Snapshots at any point in time │ │
│ │ • Retention policies (7 days / 30 days / 12 months) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Options: MinIO (self-hosted) / Backblaze B2 ($0.5/GB/mo) / AWS S3│
└──────────────────────────────────────────────────────────────────┘
Step 1: Install Restic
Install Restic on all VPS instances you want to back up:
# Ubuntu/Debian
curl -fsSL https://github.com/restic/restic/releases/latest/download/restic_0.17.1.deb \
-o /tmp/restic.deb && dpkg -i /tmp/restic.deb
# Or download directly from GitHub
wget https://github.com/restic/restic/releases/latest/download/restic_0.17.1_linux_amd64.tar.gz
tar xzf restic_*.tar.gz
sudo mv restic /usr/local/bin/
restic --version # Verify installation
Step 2: Initialize the Backup Repository
Initialize the repository on S3-compatible storage. Using Backblaze B2 as an example (best price-to-performance, $0.5/GB/month, first 1GB free egress):
# Set environment variables (add to ~/.profile)
export RESTIC_REPOSITORY="s3:s3.backblazeb2.com/your-bucket-name"
export AWS_ACCESS_KEY_ID="your-b2-application-key-id"
export AWS_SECRET_ACCESS_KEY="your-b2-application-key-secret"
export RESTIC_PASSWORD="your-strong-backup-encryption-password"
# Initialize the repository
restic init
If using a self-hosted MinIO, adjust the endpoint:
export RESTIC_REPOSITORY="s3:minio.your-domain.com/backup-bucket"
export AWS_ENDPOINT_URL="https://minio.your-domain.com"
export AWS_S3_FORCE_PATH_STYLE="true"
Step 3: Write the Backup Script
Create a reusable backup script at /usr/local/bin/restic-backup.sh:
#!/bin/bash
set -euo pipefail
# ===== Configuration =====
RESTIC_REPOSITORY="s3:s3.backblazeb2.com/vps-backup"
AWS_ACCESS_KEY_ID="${B2_ID}"
AWS_SECRET_ACCESS_KEY="${B2_SECRET}"
RESTIC_PASSWORD="${BACKUP_PASSWORD}"
TAGS="vps-primary"
# Directories to back up
BACKUP_SOURCES=(
"/etc"
"/var/www"
"/home"
"/opt/app-data"
)
# Exclude rules
EXCLUDE_FILE="/etc/restic-exclude.txt"
# ===== Execute Backup =====
LOG_FILE="/var/log/restic-backup.log"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
echo "[$TIMESTAMP] Starting backup..." >> "$LOG_FILE"
# Run backup, keeping recent snapshots
restic backup \
--tag "$TAGS" \
--exclude-file "$EXCLUDE_FILE" \
"${BACKUP_SOURCES[@]}" \
>> "$LOG_FILE" 2>&1
# Forget old snapshots: keep 7 daily, 4 weekly, 12 monthly
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--prune
echo "[$TIMESTAMP] Backup complete, old snapshots pruned" >> "$LOG_FILE"
Create the exclude file /etc/restic-exclude.txt:
/var/cache
/var/tmp
/tmp
/proc
/sys
/dev
*.log
*.tmp
swap
Make it executable:
chmod +x /usr/local/bin/restic-backup.sh
Step 4: Schedule Automated Backups
Use cron for daily automated backups:
# Edit crontab
crontab -e
# Run backup daily at 2:00 AM
0 2 * * * /usr/local/bin/restic-backup.sh
Also add credential variables to /etc/environment to avoid passing them each time:
echo 'B2_ID=your-application-key-id' >> /etc/environment
echo 'B2_SECRET=your-application-key-secret' >> /etc/environment
echo 'BACKUP_PASSWORD=your-encryption-password' >> /etc/environment
Step 5: Verify and Test Restores
Regular verification is critical — a backup you can’t restore from doesn’t exist:
# View backup history
restic snapshots
# Verify repository integrity
restic check
# List contents of the latest snapshot
restic ls latest
# Restore to a directory
restic restore latest --target /tmp/restore-test
# Restore a single file
restic restore latest --include="/etc/nginx/nginx.conf" --target /tmp/
Advanced: Multi-Server Centralized Backup
If you manage multiple VPS instances, two strategies work well:
Strategy A: Central Backup Server (Recommended)
Run a single Restic repository on one VPS; other servers push backups via SSH:
# On the backup server, initialize the central repo
restic init --repo /data/backups/main
# On each source server, push to the central repo via SSH
restic backup --repo ssh:backup-server:/data/backups/main /etc /var/www
All data is stored in one place, making management, retrieval, and recovery straightforward.
Strategy B: Tiered Backup + Geographic Redundancy
Local fast backup on disk, with async replication to remote S3:
# Local fast backup (disk)
restic backup --repo /data/backups/local /var/www
# Remote redundancy backup (S3, async)
restic backup --repo s3:s3.backblazeb2.com/remote-backup /var/www
Cost Estimation
| Storage Option | Price | Best For |
|---|---|---|
| Backblaze B2 | $0.5/GB/month | Personal/small projects, best value |
| Aliyun OSS (Standard) | $0.24/GB/month | China-based users, low latency |
| AWS S3 Standard | $0.023/GB/month (first year) | AWS ecosystem users |
| Self-hosted MinIO (local disk) | Disk cost only | Maximum control, no extra fees |
Typical scenario: Backing up 200GB using Backblaze B2 costs approximately $100/month. Compare that to $500+ for equivalent provider snapshots.
Security Checklist
- Use a strong random backup password (32+ characters recommended)
- Run
restic checkregularly to verify integrity - Perform a restore drill at least quarterly
- Don’t hardcode keys in scripts — use environment variables or a secrets manager
- Enable geographic redundancy (at least two backup copies)
- Set snapshot retention policies to prevent unbounded growth
Summary
Restic paired with S3-compatible object storage gives VPS operators a low-cost, highly secure, fully self-controlled backup solution. Compared to commercial backup services and cloud snapshots, it offers significant advantages in data encryption, cross-region disaster recovery, and cost control.
From installation to your first successful backup takes less than 15 minutes. Set up automated backups for your VPS today and eliminate data loss risk for good.
