Skip to content

Database backups

Every night at 3 AM, a script backs up the four PostgreSQL databases of the infrastructure, the Odoo filestore, and the N8N encryption key to Google Drive. If anything fails, an alert fires immediately through the Notification Hub.

DataSourceTypical size
N8N databasen8n-stack PostgreSQL~500 MB
Odoo database (guig_db)odoo-stack PostgreSQL~200 MB
TimeTrackr databasetimetrackr-stack PostgreSQL~10 MB
Odoo filestore/var/lib/odoo/filestore/~1 GB
N8N keyN8N_ENCRYPTION_KEYA few bytes

ProblemWithout auto backupWith auto backup
Data lossDB corruption = everything goneRestore from GDrive
Forgotten backups”When was the last one?”Daily 3 AM cron
No retentionLocal disk fills upLocal rotation 7 d, GDrive 30 d
Silent failureBackup fails, nobody knowsInstant Telegram alert

scripts/backup-databases.sh

failure

Host cron · 03:00 daily

pg_dump · 3 DB via docker exec

gzip dumps

tar Odoo filestore

Export N8N_ENCRYPTION_KEY

rclone copy → GDrive

Local rotation · -7 d

GDrive rotation · -30 d

/backups/ · retention 7 d

GDrive · retention 30 d

Notification Hub · alert on failure

The script is triggered by crontab at 3 AM (0 3 * * *). It runs in order:

  1. PostgreSQL dumppg_dump of every database via docker exec
  2. Compression — gzip of the dumps
  3. Filestore copy — tar archive of the Odoo filestore
  4. N8N key export — extracts N8N_ENCRYPTION_KEY from environment variables
  5. GDrive uploadrclone copy to the remote folder
  6. Local rotation — deletes files older than 7 days
  7. GDrive rotation — deletes files older than 30 days

If a step fails, the script keeps going and sends an error notification to the Notification Hub at the end.

StorageRetentionRotation
Local (/backups/)7 daysDaily script
Google Drive30 daysrclone delete --min-age 30d
Fenêtre de terminal
# View the latest local backups
ls -lh /backups/
# View the logs
tail -20 /var/log/backup-databases.log
# Check the cron entry
crontab -l | grep backup

LimitImpactMitigation
No restore testIssues surface at the worst possible momentMonthly test planned
GDrive single pointIf GDrive is down, no remote backupAdd a second provider (S3)
No incremental backupFull dump every nightAcceptable at current volumes

If data volume grows:

  • Switch to incremental backups (PostgreSQL WAL archiving)
  • Compress with zstd instead of gzip (faster, better ratio)

If fast restoration is required:

  • Automated restore script
  • Weekly automatic restore test in an ephemeral container