Werkspur Docs Zur Website

Backup & Wiederherstellung

Automatische Sicherung

Ein eigener Backup-Container läuft neben der Datenbank, solange der Stack läuft. Die erste Sicherung entsteht sofort beim Start, danach alle 24 Stunden.

Der Backup-Container läuft mit demselben Postgres-Image wie die Datenbank selbst. Client und Server passen damit immer zusammen, auch nach einem Versions-Update des Stacks.

Jeder Lauf schreibt einen pg_dump im Custom-Format. Dieses Format lässt sich mit pg_restore einspielen. Die Datei entsteht zuerst mit der Endung .dump.tmp. Nur nach einem erfolgreichen pg_dump benennt das Skript sie atomar in .dump um. Nach einem fehlgeschlagenen Lauf entfernt es die temporäre Datei. Eine vorhandene .dump-Datei stammt daher aus einem abgeschlossenen Dump-Lauf. Die Sicherung umfasst die gesamte PostgreSQL-Datenbank in diesem Stand, einschließlich Aufträgen, Losen, Ereignissen, Audit-Kette und verschlüsselten Secret-Werten.

Alte Stände entfernt der Dienst selbst. FOUNDRY_BACKUP_RETENTION_DAYS legt die Anzahl der Tage fest, standardmäßig 14. Schlägt ein Lauf fehl, protokolliert der Dienst den Fehler und versucht nach dem nächsten 24-Stunden-Intervall einen neuen Dump. Er führt keinen unmittelbaren Wiederholungsversuch aus und holt den ausgefallenen Zeitpunkt nicht nach.

Die Sicherungen liegen unter deploy/backups/ auf dem Server. Organisieren Sie eine zusätzliche Kopie nach Ihrer eigenen Vorgabe, beispielsweise auf getrenntem Speicher. WERKSPUR überträgt Dumps nicht selbst auf ein externes Ziel. Ohne getrennte Kopie deckt der eingebaute Dienst den Verlust des gesamten Servers oder Datenträgers nicht ab.

Der vollständige Sicherungsweg führt vom temporären Dump über eine geprüfte Sicherung bis zur Wiederherstellung. Für die Freigabe eines wiederhergestellten Systems müssen sowohl der Dump als auch derselbe Master-Schlüssel vorliegen, und die abschließende Audit-Prüfung muss erfolgreich sein.

flowchart TD
    Database["Produktionsdatenbank"] -->|"alle 24 Stunden"| Temp["Temporärer Dump"]
    Temp --> DumpOK{"Dump erfolgreich?"}
    DumpOK -->|"Nein"| Delete["Temporäre Datei entfernen"]
    Delete --> Wait["Nächstes Intervall abwarten"]
    DumpOK -->|"Ja"| Dump["Abgeschlossene Sicherung"]
    Dump --> Copy["Getrennte Kopie"]
    Dump --> Verify["Neueste Sicherung verifizieren"]
    Verify --> Scratch["Temporäre Datenbank"]
    Scratch --> Audit["Audit-Kette prüfen"]
    Audit --> Verified{"Prüfung erfolgreich?"}
    Verified -->|"Nein"| Blocked["Nicht zur Wiederherstellung freigeben"]
    Verified -->|"Ja"| Restore["In leere Datenbank einspielen"]
    Key["Derselbe Master-Schlüssel"] --> Restore
    Restore --> Start["Vollständigen Stack starten"]
    Start --> FinalAudit["Audit-Kette erneut prüfen"]
    FinalAudit --> Release{"Prüfung erfolgreich?"}
    Release -->|"Ja"| Ready["System freigeben"]
    Release -->|"Nein"| Blocked

Sicherung verifizieren

Verifizieren Sie regelmäßig, dass sich der neueste Dump einspielen und seine Audit-Kette mit der aktuellen Konfiguration prüfen lässt. Auf einem Produktivsystem verwenden Sie die Produktionsvariante; sie arbeitet ausschließlich mit den vorgebauten Images:

make production-backup-verify

Auf einem Entwicklungssystem heißt dasselbe Kommando:

make backup-verify

Das Kommando wählt die neueste Datei unter deploy/backups/, stellt sie in der temporären Datenbank foundry_restore_verify wieder her und führt werkspur verify-audit dagegen aus. Bei Erfolg entfernt es die temporäre Datenbank und schreibt:

backup-verify: PASS

PASS bestätigt für diesen Lauf, dass pg_restore den neuesten Dump ohne Fehler eingespielt hat und die Audit-Prüfung mit dem aktuell bereitgestellten Master-Schlüssel ok: true geliefert hat. Es bestätigt nicht die Verfügbarkeit einer externen Kopie oder des gesicherten Master-Schlüssels. Es testet auch nicht den vollständigen Start auf einem Ersatzserver oder externe Integrationen.

Das Skript schreibt nicht in die Produktionsdatenbank, verwendet aber denselben PostgreSQL-Server und beansprucht dort Ressourcen. Führen Sie es in einem geeigneten Betriebsfenster aus. Bei einem Fehler kann die temporäre Datenbank bestehen bleiben; der nächste Lauf entfernt sie vor dem erneuten Anlegen. Das mitgelieferte Skript setzt derzeit den Datenbankbenutzer foundry voraus. Bei einem abweichenden POSTGRES_USER müssen Sie deploy/scripts/backup-verify.sh entsprechend anpassen.

Führen Sie die Verifikation regelmäßig aus, beispielsweise wöchentlich und nach einem größeren Update. Dokumentieren Sie Ergebnis, geprüften Dateinamen und Zeitpunkt.

Die beiden Lizenzartefakte einer Produktivinstallation, das license-state-Volume und deploy/license/license.json, sind in keinem Dump enthalten. Sichern Sie beide zusätzlich, wie unter Lizenzbetrieb beschrieben.

Wiederherstellung

Wenn der Server ausfällt oder Sie auf eine neue Maschine umziehen, gehen Sie in dieser Reihenfolge vor. Die Konfigurationsebenen beschreibt Installation & Betrieb. Eine produktive Wiederherstellung spielt zusätzlich das zusammengehörige Installations-Volume und die Lizenzdatei ein, bevor die Anwendung zum ersten Mal startet; die Befehle stehen unter Lizenzbetrieb.

Die folgenden Beispiele zeigen den Entwicklungsaufruf. Auf einem Produktivsystem ersetzen Sie docker compose --env-file deploy/.env -f deploy/docker-compose.yml durch ./deploy/production-compose.sh; Unterbefehle und Dienstnamen sind identisch, und das Skript liest deploy/.env selbst.

Kopieren Sie auf einer neuen Maschine deploy/.env.example nach deploy/.env. Setzen Sie alle Compose-Pflichtwerte. Auch ein Aufruf nur für den Dienst postgres verarbeitet die Compose-Datei und benötigt deshalb Bootstrap-Zugang und FOUNDRY_SECRET_KEY. Übernehmen Sie zusätzlich die betriebsrelevante Konfiguration des Quellsystems, insbesondere denselben Seed-Profilbezeichner. Kopieren Sie den ausgewählten Dump nach deploy/backups/.

Setzen Sie vor der Wiederherstellung exakt denselben FOUNDRY_SECRET_KEY wie im Quellsystem. Ohne ihn lassen sich gespeicherte Secrets nicht entschlüsseln. Mit einem anderen Schlüssel meldet die Prüfung der vorhandenen HMAC-Kette einen Bruch. Eine Kopie der alten .env-Datei allein ist keine unabhängige Schlüsselsicherung, wenn sie nur auf dem ausgefallenen Server lag.

Starten Sie auf der neuen Maschine nicht zuerst make stack-up. Die Anwendung würde eine leere Datenbank initialisieren und Seed-Daten anlegen. Starten Sie zunächst nur PostgreSQL und warten Sie auf dessen Healthcheck. --env-file und -f sind globale Compose-Optionen und stehen deshalb vor up; der Dienstname folgt auf die Optionen von up:

docker compose --env-file deploy/.env -f deploy/docker-compose.yml \
  up -d --wait postgres

Der Befehl kehrt erst zurück, wenn PostgreSQL healthy ist. Beim ersten Start legt das Image die in POSTGRES_DB konfigurierte Datenbank an. Löschen Sie diese leere Datenbank und erstellen Sie sie neu. Die folgenden Befehle lesen Benutzer- und Datenbanknamen aus der Containerumgebung:

docker compose --env-file deploy/.env -f deploy/docker-compose.yml \
  exec -T postgres \
  sh -lc 'dropdb -U "$POSTGRES_USER" --if-exists "$POSTGRES_DB"'
docker compose --env-file deploy/.env -f deploy/docker-compose.yml \
  exec -T postgres \
  sh -lc 'createdb -U "$POSTGRES_USER" "$POSTGRES_DB"'
docker compose --env-file deploy/.env -f deploy/docker-compose.yml \
  exec -T postgres \
  sh -lc 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --no-owner' \
  < deploy/backups/foundry-<zeitstempel>.dump

Wählen Sie den zuvor verifizierten Dateinamen aus deploy/backups/. Starten Sie erst danach den vollständigen Stack, auf einem Produktivsystem mit make production-up, auf einem Entwicklungssystem mit:

make stack-up

Wenn die wiederhergestellte Benutzertabelle nicht leer ist, legt der Bootstrap keinen weiteren Admin an. Melden Sie sich mit einem Zugang des wiederhergestellten Systems an. Der Start wendet außerdem das konfigurierte Seed-Profil an und legt fehlende Seed-Einträge an; verwenden Sie deshalb den Profilbezeichner des Quellsystems.

Zum Abschluss prüfen Sie die Audit-Kette des wiederhergestellten Stands:

docker compose --env-file deploy/.env -f deploy/docker-compose.yml \
  exec -T werkspur werkspur verify-audit

"ok": true bestätigt, dass die gespeicherten Ereignis- und Prüfpunktketten unter dem bereitgestellten Schlüssel konsistent sind. "ok": false enthält eine Bruchstelle und beendet das Kommando mit einem Exit-Code ungleich null. Geben Sie das System in diesem Fall nicht für Buchungen frei. Die Interpretation des Reports beschreibt Sicherheit im Betrieb. Benutzer- und Ereignisprüfungen in der Oberfläche finden Sie unter Benutzer & Audit.

Nicht unterstützte Wiederherstellungsfunktionen

Ein separates Werkzeug für Downgrades oder eine Wiederherstellung auf einen beliebigen Zeitpunkt zwischen zwei Dumps existiert nicht. Sie können nur den Stand einer vorhandenen Dump-Datei einspielen.

Der eingebaute Dienst startet einen Dump alle 24 Stunden. Bei einem Ausfall kann der Datenverlust daher nahezu 24 Stunden betragen, bei zuvor fehlgeschlagenen Läufen auch mehr. Wenn Ihr Wiederherstellungspunktziel kürzer ist, benötigen Sie einen zusätzlichen, selbst betriebenen Sicherungsprozess.

Für die Wiederherstellung auf einem bestehenden Server stoppen Sie zuerst den Stack mit make production-down (Entwicklung: make stack-down). Beide Kommandos erhalten alle benannten Volumes. Verwenden Sie niemals down --volumes oder das Entwicklungskommando make dev-reset auf einem Produktivsystem: Damit löschen Sie neben der Datenbank auch das license-state-Volume mit der Installationsidentität. Starten Sie danach nur PostgreSQL und führen Sie dieselben Wiederherstellungsschritte aus. Ein eigenständiges Rückgängig-Kommando für Updates gibt es nicht.