Backup Cross-Region Storage Box Mirror
Akira mirrors the existing ADR-0012 PostgreSQL backup layout from the primary
Hetzner Storage Box in fsn1 to a second Storage Box in nbg1.
This runbook follows the accepted backup strategy:
- nightly
pg_dump --format=customfiles in/backups/pg; - continuous WAL archive files in
/backups/wal; - restore validation through the existing DR drill flow.
Provisioning
Create the second Storage Box manually in Hetzner Cloud Console:
- product: Storage Box BX11, 1 TB;
- location:
nbg1; - subaccount:
akira-backup-mirror; - authentication: ASCII password plus SSH public key.
Populate and encrypt the vault values:
vault_storagebox_mirror_host: "u123456.your-storagebox.de"
vault_storagebox_mirror_user: "akira-backup-mirror"
vault_storagebox_mirror_password: "<password>"
vault_storagebox_mirror_ssh_key: "<encrypted private key block>"
vault_storagebox_mirror_host_pubkey: "u123456.your-storagebox.de ssh-ed25519 ..."
After provisioning, set backup_mirror_enabled: true for the DB primary host
and run the timescaledb role.
Schedule
akira-backup-mirror.timer runs every 6 hours at 00:30, 06:30, 12:30,
and 18:30 with up to 10 minutes of randomized delay.
The job copies missing files from the primary Storage Box to the mirror:
/backups/pg/akira-*.dump;/backups/wal/*.
The mirror keeps longer retention than the primary operational window:
- dumps: 45 days;
- WAL: 21 days.
Verification
Weekly verification runs Mondays at 07:00:
systemctl status akira-backup-mirror-verify.timer
journalctl -u akira-backup-mirror-verify.service -n 100
Manual check:
sudo BACKUP_MIRROR_ENV_FILE=/etc/akira/backup-mirror.env /usr/local/bin/verify-backup-mirror.sh
The check fails if the newest mirrored dump lags the primary dump by more than 8 hours.
Alerting
backup-mirror-sync.sh writes node_exporter textfile metrics to:
/var/lib/node_exporter/textfile_collector/akira_backup_mirror.prom
Prometheus rule BackupMirrorLagHigh fires when the last successful mirror sync
is older than 8 hours for 30 minutes.
Restore From Mirror
Use the mirror if the primary fsn1 Storage Box or region is unavailable:
sudo BACKUP_MIRROR_ENV_FILE=/etc/akira/backup-mirror.env \
/usr/local/bin/dr-restore-from-mirror.sh mirror akira-dr-scratch
The script downloads the latest mirrored dump, validates it with
pg_restore --list, uploads it to the scratch host, recreates the target
database and runs pg_restore.
For the primary Storage Box path:
sudo /usr/local/bin/dr-restore-from-mirror.sh primary akira-dr-scratch
Failure Handling
If nbg1 is unavailable, the primary backup path continues to work. The mirror
job is idempotent and resumes at the next timer run, copying only missing files.
If the mirror lags:
- Check
journalctl -u akira-backup-mirror.service -n 200. - Verify both SSH keys and Storage Box host keys.
- Check free space and quota on the mirror Storage Box.
- Run
/usr/local/bin/backup-mirror-sync.shmanually after fixing access.
Cost
The pilot cost increase is one additional BX11 Storage Box in nbg1, about
EUR 4/month. Total Storage Box backup cost is about EUR 8/month.