The 3-2-1 Backup Rule
- 3 copies of your data
- 2 different storage media
- 1 offsite copy
For a Hetzner VPS, this translates to:
1. Live data on the server
2. Hetzner snapshots or backups
3. External backup to a different provider (or Hetzner Storage Box)
Hetzner Built-in Options
#### Automatic Backups ($2.88/mo for CPX42)
Hetzner offers automatic daily backups for ~20% of your server cost. These are full server images stored in a separate location.
Pros:
- Dead simple — one checkbox to enable
- Full server restore in minutes
- Stored separately from your server
Cons:
- Daily granularity only (you lose up to 24 hours of data)
- Keeps only the last 7 backups
- Not encrypted at rest
#### Manual Snapshots (Free, billed for storage)
Create point-in-time snapshots before major changes:
# Via Hetzner CLI
hcloud server create-image --type snapshot --description "pre-upgrade" YOUR_SERVER_ID
Cost: $0.012/GB/month for snapshot storage.
Database Backups
This is the most critical piece. Server snapshots aren't ideal for databases because the data might be in an inconsistent state during the snapshot.
#### PostgreSQL
# Dump all databases
pg_dumpall -U postgres > /backups/pg_dump_$(date +%Y%m%d).sql
# Or specific database
pg_dump -U postgres mydb > /backups/mydb_$(date +%Y%m%d).sql
#### Mailcow
Mailcow includes a backup script:
cd /opt/mailcow-dockerized
./helper-scripts/backup_and_restore.sh backup all
Automated Backup Script
Create a daily backup script:
#!/bin/bash
BACKUP_DIR="/backups/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# Database dumps
docker exec postgres pg_dumpall -U postgres > $BACKUP_DIR/postgres.sql
# Mailcow backup
cd /opt/mailcow-dockerized
./helper-scripts/backup_and_restore.sh backup all --delete-days 7
# Coolify volumes
docker run --rm -v coolify_data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/coolify.tar.gz /data
# Clean up old backups (keep 30 days)
find /backups -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_DIR"
Schedule with cron:
crontab -e
# Run daily at 3 AM
0 3 * * * /root/scripts/backup.sh >> /var/log/backup.log 2>&1
Offsite Backups
#### Hetzner Storage Box
Hetzner offers Storage Boxes starting at $3.81/mo for 1TB. Perfect for offsite backups:
# Sync backups to Storage Box via SFTP
rsync -avz /backups/ u123456@u123456.your-storagebox.de:backups/
#### S3-Compatible Storage
Use Hetzner Object Storage, Backblaze B2, or AWS S3:
# Using rclone
rclone sync /backups remote:my-backups/server-backups
Testing Restores
A backup you haven't tested is not a backup. Quarterly, spin up a test server and verify:
1. You can restore from the latest backup
2. Databases are consistent and queryable
3. Applications start and function correctly
4. Email data is intact
Disaster Recovery Plan
Document these for your team:
1. Where are backups stored? (Hetzner, Storage Box, S3)
2. How to create a new server (Hetzner Cloud Console)
3. How to restore from backup (step-by-step commands)
4. DNS changes needed (update A records)
5. Expected recovery time (typically 30-60 minutes)
Our Recommendation
| Component | Backup Method | Frequency | Retention |
|---|---|---|---|
| Full server | Hetzner automatic | Daily | 7 days |
| Databases | pg_dump + offsite | Daily | 30 days |
| Mailcow | Built-in script | Daily | 14 days |
| Docker volumes | tar + offsite | Weekly | 30 days |
| Config files | Git repository | On change | Unlimited |
Our complete guide includes backup scripts, cron configurations, and a tested disaster recovery runbook as part of the full VPS setup.
Want the Complete Setup Guide?
This blog post covers the basics. Our premium guide includes step-by-step commands, exact configurations, and the solutions to every gotcha we encountered.