Skip to content

Administration Update und Rollback

Dr. Alexander Papaspyrou edited this page Sep 15, 2026 · 5 revisions

Update und Rollback

Diese Verfahren stehen ab v0.6.0 zur Verfügung. Sie werden ausschließlich mit veröffentlichten Release-Artefakten in einem dedizierten Wartungscontainer ausgeführt. Der normale Anwendungscontainer ist dabei gestoppt; der Wartungscontainer veröffentlicht keinen Port und startet keinen Server.

Ein Update des Image-Verweises allein ist kein unterstütztes Upgrade. Ein Rollback ist keine Datenbank-Rückmigration.

Zielrelease und Wartungsfenster vorbereiten

  1. Lesen Sie Release Notes, bekannte Grenzen und den ausgewiesenen Migrationsumfang des Zielreleases.
  2. Planen Sie ein Wartungsfenster und sperren Sie den öffentlichen Zugriff am Reverse Proxy.
  3. Prüfen Sie, dass das konfigurierte Backup-Empfängerschlüsselpaar verfügbar ist und ein aktuelles vollständiges Backup nicht mutierend verifiziert wurde.
  4. Wählen Sie die exakte SemVer-Version des veröffentlichten Zielreleases und prüfen Sie deren Herkunft.
  5. Verwenden Sie lzug-admin aus demselben Release wie das Zielimage.
TARGET_VERSION=0.8.0
TARGET_IMAGE="ghcr.io/lxndrp/lzug-app:${TARGET_VERSION}"

gh attestation verify "oci://$TARGET_IMAGE" --repo lxndrp/lzug
docker pull "$TARGET_IMAGE"
./lzug-admin --version
./lzug-admin --build-metadata

Die CLI prüft zusätzlich selbst den kanonischen Produktnamen und die exakte SemVer-Version der Docker-Image-Referenz sowie die OCI-Labels für Quelle, Version und Commit. Einen durch Docker aufgelösten Digest nimmt sie, sofern verfügbar, nur als Diagnose- und Herkunftsinformation in den technischen Nachweis auf. Entwicklungsbuilds, bewegliche Tags, fremde Repositories und eine von der CLI abweichende Release-Identität werden vor dem Backendaufruf abgewiesen.

Wartungscontainer starten

Erstellen Sie außerhalb des Repositorys eine temporäre, nur für den Service-Account lesbare Env-Datei mit der wirksamen Laufzeitkonfiguration. Der aktive öffentliche Backup-Empfänger liegt ab v0.7.0 auditiert im Datenbestand; der private Empfängerschlüssel gehört weder in diese Datei noch in den Container.

Stoppen Sie die Referenzinstallation und starten Sie den Wartungscontainer mit demselben persistenten Volume und dem gebundenen Admin-Socket:

DATA_VOLUME="${LZUG_DATA_VOLUME:-lzug_data}"
MAINTENANCE_ENV_FILE=/geschuetzter/pfad/lzug-maintenance.env
SOCKET_DIR="${LZUG_ADMIN_SOCKET_DIR:-$PWD/var/lzug-admin}"

docker compose -f compose.yaml stop lzug
mkdir -p "$SOCKET_DIR"
chmod 0750 "$SOCKET_DIR"
docker run --detach --name lzug-maintenance \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,nodev \
  --env-file "$MAINTENANCE_ENV_FILE" \
  --env LZUG_LIFECYCLE_MAINTENANCE=true \
  --mount "type=volume,source=${DATA_VOLUME},target=/data" \
  --mount "type=bind,source=$SOCKET_DIR,target=/run/lzug-admin" \
  "$TARGET_IMAGE" \
  --host 127.0.0.1 --port 8000 \
  --admin-socket-dir /run/lzug-admin --admin-socket-gid 10001

Der Wartungscontainer darf keinen Port veröffentlichen. Das Backend weist den Lifecycle-Aufruf außerdem ab, wenn der normale backend.server der Container-Hauptprozess ist.

Upgrade durchführen

upgrade apply prüft Release-Identität, Migrationshistorie, Zielpfad und Wartungsgrenze. Die CLI erzeugt davor lokal ein age-geschütztes vollständiges Backup des aktuellen Datenstands und prüft es mit der lokalen privaten Identität, bevor eine Migration beginnt.

Bei ausstehenden Migrationen ist die ausdrückliche Bestätigung zwingend:

PRIVATE_KEY_FILE=/geschuetzter/pfad/lzug-backup.agekey
docker exec --user 10001:10001 lzug-maintenance \
  /usr/local/bin/lzug-admin --endpoint unix:///run/lzug-admin/admin.sock \
  upgrade apply \
  --backup-output ./lzug-pre-upgrade.lzug \
  --identity-file "$PRIVATE_KEY_FILE" \
  --confirm-irreversible

Die Bestätigung ersetzt weder Backup noch kryptographische und fachliche Prüfung. Ohne ausstehende Migration darf --confirm-irreversible entfallen; das vollständige Backup wird trotzdem erzeugt und geprüft.

Ein geeignetes Backup muss entschlüsselbar und vollständig sein, exakt zum Quellschema und zum ausstehenden Zielpfad passen und darf keine fehlende Pflichtkonfiguration melden. Fehlender öffentlicher Empfänger, falsche private Identität, Beschädigung, inkompatibles Schema oder ungeprüftes Zielimage brechen vor der Migration ab.

Erfolgreiches Upgrade aktivieren

Aktivieren Sie das Zielimage erst nach ok: true und vollständig abgeschlossenen Phasen:

docker rm --force lzug-maintenance
export LZUG_IMAGE="$TARGET_IMAGE"
docker compose -f compose.yaml up -d

export LZUG_ADMIN_SOCKET_DIR="$PWD/var/lzug-admin"
export LZUG_ADMIN_ENDPOINT="unix://$LZUG_ADMIN_SOCKET_DIR/admin.sock"
./lzug-admin --endpoint "$LZUG_ADMIN_ENDPOINT" system doctor
curl -fsS http://127.0.0.1:8000/api/ready

Prüfen Sie anschließend über HTTPS Anmeldung, erwartete Ausschusszuordnung und eine fachliche Stichprobe. Entfernen Sie die temporäre Wartungs-Env-Datei und geben Sie den Reverse Proxy erst nach erfolgreicher Abnahme wieder frei.

Fehlergrenzen beim Upgrade

Ein Fehler vor der Migration verändert den Datenstand nicht. Entfernen Sie den Wartungscontainer und starten Sie den unveränderten bisherigen Anwendungscontainer nur dann erneut:

docker rm --force lzug-maintenance
docker compose -f compose.yaml start lzug

Nach einem Migrations- oder Nachprüfungsfehler bleibt die Instanz gestoppt. Die JSON-Antwort nennt Fehlerphase und geheimnisfreien Namen des zuvor verifizierten Backups. Starten Sie weder altes noch neues Image, solange die Schema-Kompatibilität nicht eindeutig feststeht.

Für die Rückkehr zum vollständigen Vor-Upgrade-Datenstand gilt ausschließlich der getrennte Restore-Vertrag auf einer leeren Instanz oder mit ausdrücklich bestätigtem --replace. Der Restore muss von einem veröffentlichten Release ausgeführt werden, das dieses Backupformat und Quellschema unterstützt. Ist ein solcher Pfad nicht belegt, lassen Sie die Instanz gestoppt und nutzen Sie den Supportweg, statt SQLite oder Migrationstabellen manuell zu verändern.

Rollback ohne Datenänderung prüfen

Ein Rollback verwendet einen Wartungscontainer der gewünschten älteren Release-Version und lzug-admin aus exakt demselben älteren Release. Vorbereitung, Attestation, gestoppter Anwendungscontainer, Volume und Wartungsgrenze entsprechen dem Upgrade-Ablauf. Das Zielrelease muss diesen Lifecycle-Vertrag selbst enthalten; v0.5.0 und ältere Releases können deshalb nicht per lzug-admin upgrade rollback freigegeben werden.

docker exec --user 10001:10001 lzug-maintenance \
  /usr/local/bin/lzug-admin --endpoint unix:///run/lzug-admin/admin.sock \
  upgrade rollback

rollback verändert weder Datenbank noch Dokumente. Der Befehl gibt die ältere Release-Version nur frei, wenn diese Runtime die vollständige vorhandene Migrationshistorie kennt und keine Migration aussteht. Nach ok: true darf der Wartungscontainer entfernt, LZUG_IMAGE auf genau diese geprüfte SemVer-Version gesetzt und die Referenzinstallation wieder mit compose up -d gestartet werden.

Ein unbekannter neuerer Schemastand oder ein nur vorwärts migrierbarer Stand wird mit rollback_not_supported vor jeder Änderung abgewiesen. Es gibt keine Rückmigration, kein automatisches Datenrollback und keine heuristische SQLite-Bearbeitung.

Exit-Codes und Nachweise

  • Exit 0: Vorgang erfolgreich.
  • Exit 29: irreversible Migration noch nicht ausdrücklich bestätigt.
  • Exit 28: Rollback nicht unterstützt oder Migration fehlgeschlagen.
  • Exit 26 oder 27: Backup ungültig beziehungsweise Empfängerschlüssel unbrauchbar oder unpassend.
  • Exit 33: Release-Artefakt, Wartungsgrenze oder Lifecycle-Ausführung nicht verifiziert.

Bewahren Sie vorübergehend Zielrelease, CLI-Build-Metadaten, Zeitfenster, Backup-Artefaktname und die geheimnisfreie JSON-Antwort auf. Enthält die Antwort einen durch Docker aufgelösten Digest, gehört auch dieser automatische Herkunftsnachweis dazu. Private Schlüssel, Env-Werte, Pfade und Fachdaten gehören nicht in den Nachweis.

Der ausführbare technische Vertrag bleibt im Hauptrepository unter Betreiber-CLI kanonisch.

Clone this wiki locally