Backup & Restore Procedures
Backup Philosophy
- 3-2-1 rule: 3 copies, 2 different media, 1 offsite
- Backups that haven't been tested are not backups
- Restore procedures must be documented before a backup counts as real
Backup Targets
| What |
Method |
Destination |
Schedule |
Retention |
| Docker volumes |
tar via docker run |
NAS (nas01:/backups/docker) |
Nightly 2 AM |
30 days |
| NAS data |
Built-in NAS sync |
Azure Blob |
Nightly 3 AM |
90 days |
Config files (~/stacks/) |
Git push |
GitHub (private repo) |
On change |
Indefinite |
| VM snapshots |
Proxmox snapshot |
Local + NAS |
Weekly |
4 weeks |
Docker Volume Backup Script
Save as /usr/local/bin/backup-docker-volumes.sh:
#!/bin/bash
BACKUP_DIR="/mnt/nas/backups/docker"
DATE=$(date +%Y-%m-%d)
mkdir -p "$BACKUP_DIR/$DATE"
for VOLUME in $(docker volume ls -q); do
docker run --rm \
-v "$VOLUME":/data \
-v "$BACKUP_DIR/$DATE":/backup \
alpine tar czf "/backup/${VOLUME}.tar.gz" -C /data .
done
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +
chmod +x /usr/local/bin/backup-docker-volumes.sh
# Crontab: 0 2 * * * /usr/local/bin/backup-docker-volumes.sh >> /var/log/docker-backup.log 2>&1
Restore Procedure — Docker Volume
docker stop <container-name>
docker run --rm \
-v <volume-name>:/data \
-v /mnt/nas/backups/docker/<DATE>:/backup \
alpine tar xzf /backup/<volume-name>.tar.gz -C /data
docker start <container-name>
docker logs <container-name> --tail 50
Restore Verification Log
| Date |
What |
From Backup |
Result |
Notes |
| YYYY-MM-DD |
Grafana volume |
YYYY-MM-DD |
✅ Success |
— |