Zum Hauptinhalt springen

Datenbanken in Containern sichern

Wenn du eine Datenbank als Container betreibst, wird deren Volume vom regulären mittwald Projekt-Backup mitgesichert. Das schützt dich davor, das Volume zu verlieren — es garantiert aber nicht, dass die Datenbankdateien darin wiederherstellbar sind.

Ein Projekt-Backup kopiert das Volume im laufenden Betrieb. Die Datenbank hält Daten im Arbeitsspeicher, in Write-Ahead-Logs und in nur teilweise geschriebenen Pages — eine Kopie zu einem beliebigen Zeitpunkt kann also einen zerrissenen Zustand erwischen. Die Wiederherstellung kann funktionieren, eine Crash Recovery erfordern oder fehlschlagen. Du merkst es erst im Ernstfall.

Ein SQL-Dump vermeidet das: Die Datenbank selbst schreibt einen konsistenten Abzug ihres Inhalts. Diese Anleitung zeigt, wie du einen solchen Dump per Cronjob einrichtest, sodass beim Projekt-Backup immer eine wiederherstellbare Kopie im Volume liegt.

Funktionsweise

Das Setup besteht aus drei Bausteinen, die aufeinander aufbauen:

  1. Ein Cronjob führt einen Dump-Befehl in deinem Datenbank-Container aus.
  2. Der Dump wird als komprimierte .sql.gz-Datei in ein Volume geschrieben. Alte Dumps werden nach einer Aufbewahrungsfrist gelöscht.
  3. Das mittwald Projekt-Backup erfasst dieses Volume bei seinem regulären Lauf, sodass der Dump zusammen mit allem anderen im Projekt gesichert wird.

Du erhältst damit zwei Schichten: Das Projekt-Backup stellt das Volume wieder her, der Dump darin stellt die Datenbank wieder her.

Voraussetzungen

Für diese Anleitung benötigst du:

  • Ein mittwald Projekt mit einem Hosting-Produkt, das Container-Workloads unterstützt
  • Einen laufenden PostgreSQL-, MariaDB- oder MySQL-Container
  • Für den CLI- und API-Weg: die mittwald CLI (mw) installiert und eingeloggt (siehe die CLI-Dokumentation) sowie die Stack-ID und den Service-Namen des Containers (mw stack list und mw container list zeigen beides an). Alle Schritte bis einschließlich der Überprüfung funktionieren auch vollständig im mStudio UI.

Schritt 1: Ablageort des Dumps

Der Dump landet in einem Unterverzeichnis des Volumes, das bereits deine Datenbankdaten enthält. Dieses Volume wird vom Projekt-Backup erfasst, der Dump wird also mitgesichert — ein zusätzliches Volume und eine Änderung am Stack sind nicht nötig.

Genau so machen es auch die Container-Templates:

  • PostgreSQL: /var/lib/postgresql/backups
  • MariaDB und MySQL: /var/lib/mysql/backups

Schritt 2: Dump-Befehl auswählen

Die folgenden Befehle schreiben einen mit Zeitstempel versehenen, gzip-komprimierten Dump und löschen Dumps, die älter als sieben Tage sind. Schlägt der Dump fehl, brechen sie ab, ohne eine abgeschnittene Datei zu hinterlassen — ein fehlgeschlagener Lauf überschreibt also nie dein letztes funktionierendes Backup mit einem kaputten.

Passe den Pfad hinter d= an, falls dein Volume an einer anderen Stelle gemountet ist (siehe Schritt 1).

sh -lc 'set -e; d=/var/lib/postgresql/backups; mkdir -p "$d";
f=$d/backup_$(date +%F_%H%M%S).sql;
{ pg_dumpall -h localhost -U "$POSTGRES_USER" -f "$f"; } || { rm -f "$f"; exit 1; };
gzip "$f";
find "$d" -name "backup_*.sql.gz" -type f -mtime +7 -delete'

pg_dumpall sichert den gesamten Cluster inklusive aller Datenbanken und Rollen. Die Anmeldung über localhost funktioniert ohne Passwort, weil die offiziellen Images in ihrer generierten pg_hba.conf lokale TCP-Verbindungen mit trust zulassen.

Um stattdessen nur eine einzelne Datenbank zu sichern, ersetze pg_dumpall durch pg_dump -h localhost -U "$POSTGRES_USER" -d "$POSTGRES_DB".

Schritt 3: Cronjob anlegen

  1. Navigiere zu dem Projekt, in dem dein Datenbank-Container läuft.
  2. Wähle in der Seitenleiste unter "Komponenten" den Menüpunkt "Cronjobs".
  3. Klicke auf "Anlegen".
  4. Vergib einen Namen und stelle das Ziel von "App" auf "Container" um.
  5. Wähle unter "Verknüpfter Container" deinen Datenbank-Container aus.
  6. Trage den Dump-Befehl aus Schritt 2 unter "Auszuführender Befehl" ein.
  7. Belasse das Intervall auf "Cron-Syntax" und trage einen Zeitplan ein, zum Beispiel 0 3 * * * für einen täglichen Lauf um 03:00 Uhr. Setze die Zeitzone auf Europe/Berlin.
  8. Klicke auf "Anlegen".

Der Dialog hat kein Feld für Fehlerbenachrichtigungen. Richte sie im Anschluss ein: Öffne den Cronjob und klicke im Abschnitt "Fehlerbehandlung" auf "Bearbeiten", um Timeout und E-Mail-Adresse zu hinterlegen. Standardmäßig benachrichtigt mittwald dich ab dem ersten fehlgeschlagenen Lauf.

Lege den Dump zeitlich so, dass er vor deinem Projekt-Backup abgeschlossen ist — und außerhalb der Hauptlastzeiten.

Schritt 4: Das Backup überprüfen

Ein Backup, das du nie getestet hast, ist eine Annahme und kein Backup. Löse den Cronjob einmal manuell aus und prüfe das Ergebnis.

  1. Öffne den Cronjob und klicke im Abschnitt "Intervall" auf "Jetzt ausführen".
  2. Wechsle auf den Tab "Historie". Dort erscheint der Lauf mit Datum und Laufzeit.
  3. Ein fehlgeschlagener Lauf ist mit "Ausführung fehlgeschlagen" markiert. Öffne bei diesem Eintrag das Menü "..." und wähle "Log anzeigen" — dort stehen Exit-Code und Fehlerausgabe.

Auch die Cronjob-Übersicht kennzeichnet fehlschlagende Cronjobs mit "Ausführung fehlgeschlagen". Ein Blick in diese Liste zeigt dir also, ob deine Backups noch laufen. Mach dir das zur Gewohnheit — ein Backup-Cronjob kann wochenlang fehlschlagen, ohne dass sonst etwas auffällt.

Eine Laufzeit von 0 Sekunden zusammen mit einem Fehlschlag bedeutet meist, dass der Dump gar nicht erst eine Verbindung zur Datenbank bekommen hat.

Wiederhole diese Prüfung nach jeder Änderung an der Datenbankversion, am Volume-Layout oder am Dump-Befehl.

Einen Dump wiederherstellen

Stelle zuerst das Volume aus dem Projekt-Backup wieder her, falls der Container selbst nicht mehr existiert, und spiele anschließend den Dump in die laufende Datenbank ein.

Ein Restore führt einen Befehl im Container aus — das bietet das mStudio UI von sich aus nicht. Dafür gibt es drei Wege:

  • Web-SSH — installiere die kostenlose Extension 1-Click Web-SSH für Apps & Container aus dem Marktplatz. Sie gibt dir ein Terminal für Apps und Container direkt im mStudio, ohne lokale CLI und ohne SSH-Schlüssel. Im selben Terminal kannst du auch die Dump-Dateien im Volume ansehen.
  • CLImw container ssh <container-id> öffnet eine Shell im Container.
  • Beliebiger SSH-Clientmw container ssh <container-id> --info gibt Hostname und Benutzernamen aus, ohne sich zu verbinden. Damit kannst du OpenSSH oder jeden anderen Client nutzen: ssh <benutzername>@<hostname>.

Alle drei Wege bringen dich in den Container. Sieh dir dort zuerst an, welche Dumps vorliegen — bei MariaDB und MySQL liegt das Verzeichnis unter /var/lib/mysql/backups (siehe Schritt 1):

user@container $ ls -la /var/lib/postgresql/backups

Anschließend spielst du den gewünschten Dump ein:

user@container $ gunzip -c /var/lib/postgresql/backups/backup_2026-09-07_030000.sql.gz | psql -h localhost -U "$POSTGRES_USER" -d postgres

Ein pg_dumpall-Dump legt Rollen und Datenbanken neu an. Spielst du ihn in einen Cluster ein, in dem diese bereits existieren, meldet psql dafür already exists-Fehler und fährt fort — die Tabellendaten werden trotzdem wiederhergestellt. Für einen sauberen Restore löschst du die Zieldatenbank vorher und legst sie neu an, oder du spielst den Dump in einen leeren Container ein.

Da diese Dumps die Rollendefinitionen (PostgreSQL) beziehungsweise die Systemdatenbank mysql (MariaDB und MySQL) enthalten, werden Datenbankbenutzer und deren Passwörter zusammen mit den Daten wiederhergestellt.

Weiterführende Ressourcen