Zum Inhalt springen

Aktualisieren und sichern

Ein Update ist bei GoodWorkshop derselbe Ablauf wie die Installation: Bei jedem Start läuft dieselbe Kette aus Prüfung und Migration. Vorher kommt immer eine Sicherung. Die Details stehen in der README unter Updating und Backing up sowie in docs/installation-and-upgrade.md.

Welche Versionen es gibt, steht auf der Release-Seite. Aus dem Verzeichnis mit der compose.yaml:

Terminal-Fenster
# 1. Back up. An upgrade without a backup is a bet.
scripts/backup.sh before-upgrade-$(date +%F).sql.gz
# 2. Fetch the new image. With GW_VERSION=latest that is all;
# with a pinned version, point GW_VERSION in the .env at the new tag first.
docker compose pull
# 3. Bring it up.
docker compose --profile tls up -d

Mit einer festen Version trägst du vor Schritt 2 die neue Nummer in GW_VERSION ein — ohne „v“. Ohne Profil tls lässt du --profile tls weg.

migrate läuft bei jedem Start, und app wartet darauf. Ein Container, der gegen ein Schema liefe, das er nicht versteht, kommt so gar nicht erst hoch.

Schritt Was er tut
db-bootstrap.mjs legt Rollen an und setzt ihre Passwörter
preflight.mjs liest nur und prüft, ob die Daten zu den Migrationen passen
migrate.mjs spielt ausstehende Migrationen ein
provision.mjs richtet Bausteintypen ein

Findet die Vorprüfung Zeilen, die einer Migration im Weg stehen, bricht migrate mit „MIGRATION STOPPED“ ab. Die Datenbank ist dann unverändert — es gibt nichts zurückzurollen. Die Meldung nennt die betroffenen Zeilen, die Abfrage, mit der du sie ansiehst, und die Entscheidung, die zu treffen ist. Danach startest du mit demselben Befehl neu.

Was ein Update finden würde, siehst du auch ohne zu aktualisieren:

Terminal-Fenster
docker compose run --rm migrate node scripts/preflight.mjs

Ein Updater wie Watchtower ersetzt nur den Container, den er beobachtet. Der Dienst migrate läuft dabei nie, und die neue App würde gegen das alte Schema laufen. Dafür gibt es GW_MIGRATE_ON_START=1 zusammen mit einer compose.override.yaml aus der README (Automatic updates). Der Preis: app hält dann auch die Passwörter des Superusers und von gw_owner, und die Rollentrennung ist für diesen Container aufgehoben. Entscheide das bewusst.

Die Datenbank ist der vollständige Bestand, Logos eingeschlossen — sie sind Zeilen, keine Dateien. Ein Dump genügt:

Terminal-Fenster
scripts/backup.sh goodworkshop-$(date +%F).sql.gz

Nimm das Skript statt einer handgeschriebenen pg_dump-Zeile. Die Zeile legt auch dann eine Datei an, wenn nichts gesichert wurde. Das Skript schreibt erst daneben, prüft, ob der Dump bis zu seiner Abschlusszeile durchgelaufen ist, und gibt ihm erst dann den endgültigen Namen.

Der Anwendungsschlüssel entschlüsselt die Mail-Zugangsdaten, die in der Oberfläche eingegeben wurden. Er steht nicht im Dump:

Terminal-Fenster
docker compose exec -T app cat /run/db-secrets/app/secret-key > goodworkshop-key.txt

Geht er verloren, kommt die Sicherung mit leeren Mail-Zugangsdaten zurück. Alles andere — Workshops, Mitglieder, Branding — übersteht das, die Zugangsdaten gibst du einmal neu ein.

Genau drei Dinge: der Dump, der Anwendungsschlüssel und die .env. Die Datenbank-Passwörter nicht — die erzeugt der Stack bei Bedarf neu. Prüfe, was im Archiv steht, nicht nur, ob es da ist. Ein gescheiterter Dump kann ein gültiges, aber leeres gzip-Archiv hinterlassen:

Terminal-Fenster
gzip -dc goodworkshop.sql.gz | tail -c 400 | grep -c 'dump complete'

Für Sicherungen außer Haus liegen drei Skripte im Repo, gedacht als systemd-Timer:

Skript Was es beantwortet Wo es läuft
scripts/backup-offsite.sh Liegt der heutige Stand verschlüsselt woanders? auf dem Server, täglich
scripts/backup-verify.sh Kommt die Sicherung tatsächlich zurück? auf dem Server, wöchentlich
scripts/backup-freshness.sh Wird überhaupt noch gesichert? auf einem anderen Rechner, täglich

Konfiguration und systemd-Units stehen in der README.

Die Datenbank-Passwörter stehen nicht im Dump, und eine Wiederherstellung auf einem neuen Server braucht sie auch nicht: secrets erzeugt neue, und migrate setzt sie auf die Rollen. Die Rollen selbst sind in keinem Dump enthalten; sie legt db-bootstrap.mjs an. Zurück brauchst du also den Dump, den Anwendungsschlüssel und die .env.

Einen fertigen Wiederherstellungsbefehl für die laufende Installation dokumentiert das Repo nicht. Wie ein Dump in ein frisches Postgres zurückgelesen wird, zeigt scripts/backup-verify.sh: Es macht genau das in Wegwerf-Containern, ohne den Produktiv-Stack zu berühren. Probier die Wiederherstellung aus, bevor du sie brauchst.