Introduction to Restic + Rclone
Restic is a fast, secure, and efficient backup program that supports multiple storage backends. When combined with Rclone, you gain access to over 40 cloud storage providers, enabling a truly multi-cloud backup strategy. This guide walks you through setting up Restic with Rclone to back up your VPS data to multiple cloud destinations simultaneously.
Why Multi-Cloud Backups?
Relying on a single backup destination creates a single point of failure. Multi-cloud backups ensure that even if one provider experiences downtime, data loss, or policy changes, your data remains accessible from alternative locations. This approach aligns with the 3-2-1 backup rule: three copies, two different media types, one offsite.
Installing Restic and Rclone
# Install Restic
sudo apt update
sudo apt install -y restic
# Install Rclone
curl https://rclone.org/install.sh | sudo bash
# Verify installations
restic version
rclone version
Configuring Rclone Remotes
Set up multiple cloud storage backends. We will configure Backblaze B2, Wasabi, and Google Cloud Storage:
# Configure interactively
rclone config
# Or create config directly in ~/.config/rclone/rclone.conf
[b2-backup]
type = b2
account = YOUR_B2_KEY_ID
key = YOUR_B2_APP_KEY
[wasabi-backup]
type = s3
provider = Wasabi
access_key_id = YOUR_WASABI_KEY
secret_access_key = YOUR_WASABI_SECRET
region = us-east-1
endpoint = s3.wasabi.com
[gcs-backup]
type = google cloud storage
project_number = YOUR_PROJECT
service_account_file = /root/gcs-service-account.json
Initializing Restic Repositories
# Set a strong repository password
export RESTIC_PASSWORD="your-strong-encryption-password"
# Initialize repositories on each backend
restic -r rclone:b2-backup:my-server-backup init
restic -r rclone:wasabi-backup:my-server-backup init
restic -r rclone:gcs-backup:my-server-backup init
Password Management
# Create password file with restricted permissions
echo "your-strong-encryption-password" > /root/.restic-password
chmod 600 /root/.restic-password
export RESTIC_PASSWORD_FILE=/root/.restic-password
Multi-Cloud Backup Script
#!/bin/bash
# /usr/local/bin/multi-cloud-backup.sh
set -euo pipefail
export RESTIC_PASSWORD_FILE="/root/.restic-password"
LOG_FILE="/var/log/multi-cloud-backup.log"
LOCK_FILE="/var/lock/multi-cloud-backup.lock"
BACKENDS=("b2-backup:my-server-backup" "wasabi-backup:my-server-backup" "gcs-backup:my-server-backup")
BACKUP_PATHS=("/etc" "/home" "/var/www" "/var/lib/mysql" "/opt/apps")
log() { echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $1" | tee -a "$LOG_FILE"; }
exec 200>"$LOCK_FILE"
flock -n 200 || { log "ERROR: Another backup is running"; exit 1; }
log "Dumping MySQL databases..."
mysqldump --all-databases --single-transaction --quick \
--triggers --routines --events > /tmp/mysql-all-databases.sql 2>>"$LOG_FILE"
FAILED=0
for backend in "${BACKENDS[@]}"; do
log "Backing up to rclone:$backend..."
if restic -r "rclone:$backend" backup \
${BACKUP_PATHS[@]} \
--exclude="*.tmp" --exclude="node_modules" --exclude=".git" \
--tag "automated" --tag "$(hostname)" \
--verbose 2>>"$LOG_FILE"; then
log "SUCCESS: $backend completed"
else
log "ERROR: $backend failed"
FAILED=$((FAILED + 1))
fi
done
for backend in "${BACKENDS[@]}"; do
restic -r "rclone:$backend" forget \
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune 2>>"$LOG_FILE"
done
rm -f /tmp/mysql-all-databases.sql
[ $FAILED -gt 0 ] && exit 1
log "All backups completed successfully"
Scheduling Automated Backups
chmod +x /usr/local/bin/multi-cloud-backup.sh
# Crontab - daily at 2 AM
0 2 * * * /usr/local/bin/multi-cloud-backup.sh
# Or systemd timer
cat > /etc/systemd/system/multi-cloud-backup.timer << EOF
[Unit]
Description=Multi-Cloud Backup Timer
[Timer] 02:00:00
Persistent=true
RandomizedDelaySec=600
[Install]
WantedBy=timers.target
EOF
systemctl enable --now multi-cloud-backup.timer
Restoring from Multi-Cloud Backups
# List snapshots from any backend
restic -r rclone:b2-backup:my-server-backup snapshots
# Restore specific files
restic -r rclone:wasabi-backup:my-server-backup restore latest \
--target /tmp/restore --include "/var/www/mysite"
# Mount as filesystem for browsing
mkdir /mnt/backup
restic -r rclone:b2-backup:my-server-backup mount /mnt/backup &
Bandwidth and Performance Tuning
# Limit bandwidth in rclone.conf
[b2-backup]
type = b2
bwlimit = 50M
# Increase parallelism
export RCLONE_TRANSFERS=8
export RCLONE_CHECKERS=16
Security Best Practices
- Use a unique, strong password for each Restic repository
- Store credentials in environment variables, not config files
- Rotate cloud API keys quarterly
- Test restores monthly from each backend
- Enable server-side encryption on cloud buckets as an additional layer
- Use dedicated backup-only API keys with minimal permissions