Infrastruktur: Tägliches PostgreSQL-Backup mit 1 GB Rotation #87

Closed
opened 2026-05-17 08:48:19 +00:00 by jreinemann-euris · 1 comment
jreinemann-euris commented 2026-05-17 08:48:19 +00:00 (Migrated from github.com)

Kontext

Die PostgreSQL-Datenbank auf dem VPS braucht ein automatisches Backup, um Datenverlust zu vermeiden.

Akzeptanzkriterien

1. Tägliches Backup um 03:00 Uhr

  • Cronjob oder Container-basierter Scheduler führt täglich um 03:00 UTC ein pg_dump der Krisenvorrat-Datenbank aus
  • Backup-Dateien werden komprimiert gespeichert (z.B. .sql.gz)
  • Dateiname enthält Timestamp (z.B. krisenvorrat_2026-05-17_0300.sql.gz)
  • Skip bei unveränderter DB: Vor dem Backup prüfen, ob sich seit dem letzten Backup etwas geändert hat (z.B. Checksum/Hash des Dumps mit dem letzten vergleichen). Falls keine Änderung → kein neues Backup anlegen

2. Speicherlimit 1 GB

  • Nach jedem Backup wird geprüft, ob die Gesamtgröße aller Backups 1 GB überschreitet
  • Falls ja: älteste Backups werden gelöscht, bis die Gesamtgröße wieder unter 1 GB liegt

3. Deployment

  • Backup-Lösung ist in docker-compose.yml integriert (eigener Service oder Erweiterung des bestehenden Setups)
  • Backup-Verzeichnis ist als Volume gemountet, damit Backups bei Container-Neustart erhalten bleiben

4. Verifizierung

  • Manueller Test: Backup-Skript einmal manuell ausführen und prüfen, ob die .sql.gz-Datei valide ist (gunzip -t + psql-Import auf Testinstanz)
  • Rotation: Prüfen, dass bei Überschreitung von 1 GB die ältesten Dateien entfernt werden

Technische Hinweise

  • Server läuft auf VPS (1984 Hosting, Island) mit Docker
  • PostgreSQL läuft bereits als Container (docker-compose.yml)
  • Bewährte Optionen: pg_dump per Cronjob im Container, oder dedizierter Backup-Container (z.B. prodrigestivill/postgres-backup-local)
  • Backup-Verzeichnis: z.B. /data/backups auf dem Host
## Kontext Die PostgreSQL-Datenbank auf dem VPS braucht ein automatisches Backup, um Datenverlust zu vermeiden. ## Akzeptanzkriterien ### 1. Tägliches Backup um 03:00 Uhr - [ ] Cronjob oder Container-basierter Scheduler führt täglich um 03:00 UTC ein `pg_dump` der Krisenvorrat-Datenbank aus - [ ] Backup-Dateien werden komprimiert gespeichert (z.B. `.sql.gz`) - [ ] Dateiname enthält Timestamp (z.B. `krisenvorrat_2026-05-17_0300.sql.gz`) - [ ] **Skip bei unveränderter DB:** Vor dem Backup prüfen, ob sich seit dem letzten Backup etwas geändert hat (z.B. Checksum/Hash des Dumps mit dem letzten vergleichen). Falls keine Änderung → kein neues Backup anlegen ### 2. Speicherlimit 1 GB - [ ] Nach jedem Backup wird geprüft, ob die Gesamtgröße aller Backups 1 GB überschreitet - [ ] Falls ja: älteste Backups werden gelöscht, bis die Gesamtgröße wieder unter 1 GB liegt ### 3. Deployment - [ ] Backup-Lösung ist in `docker-compose.yml` integriert (eigener Service oder Erweiterung des bestehenden Setups) - [ ] Backup-Verzeichnis ist als Volume gemountet, damit Backups bei Container-Neustart erhalten bleiben ### 4. Verifizierung - [ ] Manueller Test: Backup-Skript einmal manuell ausführen und prüfen, ob die `.sql.gz`-Datei valide ist (`gunzip -t` + `psql`-Import auf Testinstanz) - [ ] Rotation: Prüfen, dass bei Überschreitung von 1 GB die ältesten Dateien entfernt werden ## Technische Hinweise - Server läuft auf VPS (1984 Hosting, Island) mit Docker - PostgreSQL läuft bereits als Container (`docker-compose.yml`) - Bewährte Optionen: `pg_dump` per Cronjob im Container, oder dedizierter Backup-Container (z.B. `prodrigestivill/postgres-backup-local`) - Backup-Verzeichnis: z.B. `/data/backups` auf dem Host
jreinemann-euris commented 2026-05-17 09:15:07 +00:00 (Migrated from github.com)

Abgeschlossen (2026-05-17)

Durchgeführte Aufgaben

  • backup/Dockerfile: Alpine 3.21 + postgresql-client + busybox crond (containerfreundlich, kein \setpgid)
  • backup/backup.sh: pg_dump → MD5-Checksum-Vergleich (PostgreSQL-17-Tokens \\restrict/\\unrestrict\ herausgefiltert) → gzip-komprimiertes Backup mit Timestamp → Rotation (älteste .sql.gz löschen bis < 1 GB)
  • docker-compose.yml: neuer Service \ackup, Volume \ackup_data\
  • Cronjob: täglich 03:00 UTC
  • Auf VPS deployed (\krisenvorrat-backup\ läuft)

Verifikation

  • Manueller Lauf: \krisenvorrat_2026-05-17_0913.sql.gz\ erstellt, \gunzip -t\ Exit 0
  • Skip bei unveränderter DB: zweiter Lauf → No changes since last backup. Skipping.
  • Rotation: bei 1.2 GB Testdaten → älteste Dateien gelöscht bis < 1 GB
## Abgeschlossen (2026-05-17) ### Durchgeführte Aufgaben - ✅ **backup/Dockerfile**: Alpine 3.21 + postgresql-client + busybox crond (containerfreundlich, kein \setpgid\) - ✅ **backup/backup.sh**: pg_dump → MD5-Checksum-Vergleich (PostgreSQL-17-Tokens \\\restrict\/\\\unrestrict\ herausgefiltert) → gzip-komprimiertes Backup mit Timestamp → Rotation (älteste .sql.gz löschen bis < 1 GB) - ✅ **docker-compose.yml**: neuer Service \ackup\, Volume \ackup_data\ - ✅ Cronjob: täglich 03:00 UTC - ✅ Auf VPS deployed (\krisenvorrat-backup\ läuft) ### Verifikation - Manueller Lauf: \krisenvorrat_2026-05-17_0913.sql.gz\ erstellt, \gunzip -t\ Exit 0 ✅ - Skip bei unveränderter DB: zweiter Lauf → *No changes since last backup. Skipping.* ✅ - Rotation: bei 1.2 GB Testdaten → älteste Dateien gelöscht bis < 1 GB ✅
Sign in to join this conversation.
No description provided.