feat(selfhost): add verified release updates with backups and recovery state
This commit is contained in:
@@ -53,7 +53,7 @@ Backend, Frontend, Dokumentation, Website und zentrale Dienste werden als gemein
|
||||
- Bewegliche Kanäle: `latest` und `main` zeigen nach erfolgreicher Veröffentlichung auf denselben Release.
|
||||
- Entwicklung: `dev` sowie unveränderliche `dev-sha-<vollständiger Commit>-<UUID>`-Images. Alle Komponenten eines erfolgreichen Laufs erhalten denselben Snapshot-Tag. Auch eine Wiederholung desselben Commits baut einen eigenen Snapshot. Die eingebettete Entwicklungsversion enthält Commit-Anzahl und Commit-ID.
|
||||
- Release-Builds erhalten zunächst einen eindeutigen temporären `build-<UUID>`-Tag. Diese Tags können später nach einer Aufbewahrungsfrist bereinigt werden; stabile Versionen und deren Digests müssen erhalten bleiben.
|
||||
- Release-Dateien: `CHANGELOG.md`, `release-manifest.json`, `docker-compose.selfhost.yml`, `.env.example`, `selfhost-install.sh`, `selfhost-setup.sh` und `SHA256SUMS`.
|
||||
- Release-Dateien: `CHANGELOG.md`, `release-manifest.json`, `docker-compose.selfhost.yml`, `.env.example`, `selfhost-install.sh`, `selfhost-setup.sh`, `selfhost-update.py`, `SELFHOST-UPDATES.md` und `SHA256SUMS`.
|
||||
|
||||
Das Manifest dokumentiert die Image-Digests, den Commit und SHA-256-Prüfsummen aller enthaltenen SQL-Migrationen. Es beschreibt den ausgelieferten Migrationsstand; den tatsächlich angewendeten Stand einer Installation bestimmt deren Datenbank.
|
||||
|
||||
@@ -122,7 +122,9 @@ bash /tmp/fedeo-install.sh --simple --start
|
||||
|
||||
Dieser versionierte Installer lädt die Betriebsdateien vom zugehörigen Git-Tag und schreibt `FEDEO_VERSION=3.0.0` in die neue `.env`. Vorhandene Installationen behalten ihren bisherigen Kanal, bis `FEDEO_VERSION` bewusst geändert wird. Die Dateien im Entwicklungszweig verwenden weiterhin `dev` als Rückfallwert.
|
||||
|
||||
Bei einem Update:
|
||||
Der vollständige Host-Updater einschließlich Compose-Austausch und Backup ist in [Vollständige Selfhost-Updates](selfhost-updates.md) beschrieben. Er benötigt eine Zielversion mit gepinntem MinIO und Anwendungs-Healthchecks.
|
||||
|
||||
Manueller Ablauf für ältere Releases oder abweichende Installationen:
|
||||
|
||||
1. Release Notes und Migrationshinweise lesen. Konsistentes Datenbankbackup (z. B. `pg_dump`) sowie Datei-/Objektspeicher und Konfiguration sichern. Ein TAR des laufenden PostgreSQL-Datenverzeichnisses ist kein verlässliches Datenbankbackup.
|
||||
2. Die benötigten Betriebsdateien vom gewünschten Release herunterladen; bestehende `.env` und Daten behalten. Downloads mit dessen `SHA256SUMS` überprüfen.
|
||||
|
||||
98
docs/selfhost-updates.md
Normal file
98
docs/selfhost-updates.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Vollständige Selfhost-Updates
|
||||
|
||||
`scripts/selfhost-update.py` ist der gemeinsame Update-Ablauf für die Kommandozeile und einen zukünftigen Update-Dienst. Diese Implementierung installiert noch keinen Dienst und stellt noch keinen Update-Button bereit. Der Prozess muss auf dem Docker-Host außerhalb der FEDEO-Container laufen.
|
||||
|
||||
## Voraussetzungen und Umfang
|
||||
|
||||
- Linux/amd64, Python ab 3.10, Docker Compose ab 2.24, `tar` und `du`.
|
||||
- Bestehendes Betriebsverzeichnis, standardmäßig `/opt/fedeo`, mit `.env` und `docker-compose.yml`; kein Git-Checkout.
|
||||
- Standard-Stack mit `traefik`, `db`, `minio`, `createbuckets`, `backend`, `frontend` und `node-exporter`. PostgreSQL und MinIO verwenden die lokalen Verzeichnisse `postgres/` und `minio/`.
|
||||
- Als root auf dem Server ausführen: Docker-Zugriff und Leserechte für die Daten- und Zertifikatsverzeichnisse werden benötigt. Ein entfernter Docker-Daemon wird abgewiesen.
|
||||
- Die öffentliche HTTPS-Adresse muss vom Host erreichbar sein und ein gültiges Zertifikat haben.
|
||||
- Eine Wartungsunterbrechung für alle Mandanten einplanen. Vor dem Backup werden alle laufenden Dienste außer PostgreSQL angehalten, auch der öffentliche Proxy und alle im Backend laufenden Hintergrundaufgaben. Eine separate Wartungsseite folgt mit der späteren Oberflächenintegration.
|
||||
|
||||
Der Updater verweigert externe Datenbanken, externen S3-/Seafile-Speicher, zusätzliche Dienste, Compose-Profile, geänderte Datenpfade und PostgreSQL-Imagewechsel. Dafür braucht es zunächst passende Backup-/Migrationsadapter. Eigene Einstellungen innerhalb der unterstützten Dienste können in `docker-compose.override.yml` **oder** `docker-compose.override.yaml` bleiben; der Updater verwendet diese Datei bei jedem Compose-Aufruf. Änderungen an dieser Override-Datei werden nicht überschrieben.
|
||||
|
||||
Die Zielversion muss bereits die festen MinIO-Digests und die neuen Backend-/Frontend-Healthchecks enthalten. Ältere Releases bleiben über den in `docs/releases.md` beschriebenen manuellen Ablauf installierbar. Ein Versionswechsel des Betriebssystems oder der Docker Engine gehört nicht zu diesem Ablauf.
|
||||
|
||||
## Bereitstellung
|
||||
|
||||
Neue versionierte Installer laden das Skript und diese Anleitung bereits ins Betriebsverzeichnis und berücksichtigen Python 3 bei den Basispaketen. Bestehende Installationen können `selfhost-update.py` und `SELFHOST-UPDATES.md` aus den Assets eines entsprechenden veröffentlichten Releases übernehmen. Zuerst mit dessen `SHA256SUMS` prüfen, anschließend das Skript unter `/opt/fedeo/scripts/selfhost-update.py` ablegen. Für diese erstmalige Bereitstellung ist noch ein Serverzugriff erforderlich.
|
||||
|
||||
Downloads erfolgen ausschließlich vom konfigurierten FEDEO-Repository über HTTPS. Die Dateiprüfsummen werden gegen `SHA256SUMS`, das Manifest gegen den Git-Tag geprüft. Die Prüfsummen sind **keine unabhängige Signatur**; das Vertrauen liegt beim Gitea-Server und dessen Release-Veröffentlichung. Falls das Repository privat ist, `FEDEO_RELEASE_TOKEN` mit Leserechten nur für den Aufruf setzen. Registry-Anmeldung bei Bedarf vorher über `docker login git.federspiel.tech` im Konto des Updaters durchführen. Der Updater speichert den Release-Token nicht in Statusdateien und gibt ihn bei Weiterleitungen an andere Hosts nicht weiter.
|
||||
|
||||
## Prüfen, anwenden und Status lesen
|
||||
|
||||
Neueste stabile Version suchen oder eine bestimmte Version prüfen:
|
||||
|
||||
```bash
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py check
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py check --version 3.1.0
|
||||
```
|
||||
|
||||
`3.1.0` ist ein Beispiel und muss durch einen tatsächlich veröffentlichten Zielrelease ersetzt werden. Ein anderes Betriebsverzeichnis wird mit `--directory /pfad/zur/instanz` angegeben.
|
||||
|
||||
Die Prüfung lädt die Betriebsdateien und erstellt einen Plan einschließlich `compose.diff` und Release Notes unter `/opt/fedeo/.updates/<Auftrag>/`. Sie verändert die laufende Installation nicht und lädt noch keine Docker-Images. Die JSON-Ausgabe nennt Zielversion, Commit, betroffene Dienste, geschätzten Backup-Platz und die Pfade der Vorschau. Unveröffentlichte Entwürfe und Vorabversionen werden ignoriert.
|
||||
|
||||
Beim ersten Update kennt der Updater die Herkunft der vorhandenen Compose-Datei noch nicht. Die erzeugte `compose.diff` prüfen und eigene Anpassungen in die Override-Datei übertragen. Dann den Austausch ausdrücklich akzeptieren:
|
||||
|
||||
```bash
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py apply --version 3.1.0 --accept-compose-replacement
|
||||
```
|
||||
|
||||
Für spätere Updates unveränderter, vom Updater verwalteter Compose-Dateien:
|
||||
|
||||
```bash
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py apply --version 3.2.0
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py status
|
||||
```
|
||||
|
||||
Eine explizite Zielversion ist beim Anwenden erforderlich. `apply` prüft die Release-Dateien und die tatsächliche Installation nochmals. Bei gleichen oder älteren stabilen Zielversionen wird abgebrochen. Änderungen an `.env`, Basis-Compose oder der Override-Datei während des Downloads führen ebenfalls vor der Wartungsphase zum Abbruch.
|
||||
|
||||
Während des ersten Ausbaus den Befehl in einer bestehenden persistenten Terminalsitzung ausführen. Der spätere Host-Dienst übernimmt die vom Browser unabhängige Ausführung. Ein Neustart des FEDEO-Stacks beendet diesen Host-Prozess nicht; ein Neustart des Hosts unterbricht ihn.
|
||||
|
||||
## Ablauf und Speicherung
|
||||
|
||||
1. Exklusive Host-Sperre erwerben; offene Wiederherstellungsfälle blockieren neue Updates.
|
||||
2. Release samt Prüfsummen laden, Manifest/Commit prüfen und die FEDEO-Images auf die exakten Digests setzen.
|
||||
3. Aktuelle und neue Compose-Konfiguration mit Docker Compose validieren. Projektname, Container-Identitäten, Mounts, Netzwerke und Zugangsdaten erhalten. Die Shell-Umgebung überschreibt dabei keine Werte aus der Instanz-`.env`.
|
||||
4. Speicherplatz prüfen: mindestens 5 GiB frei am Docker-Datenverzeichnis vor dem Pull sowie geschätzte Backup-Größe plus Reserve im Betriebsverzeichnis. Images laden, Backup-Platz erneut prüfen.
|
||||
5. Schreibende Dienste und Proxy anhalten. PostgreSQL bleibt für `pg_dump` aktiv.
|
||||
6. Konfiguration, Container-Metadaten, PostgreSQL-Dump im Custom-Format, globale PostgreSQL-Rollen, gestoppten MinIO-Dateispeicher und Zertifikate sichern. Dump und TAR auf Lesbarkeit prüfen und SHA-256-Prüfsummen schreiben. `backup/complete.json` markiert ein vollständig geschriebenes Backup; ein Restore-Probelauf auf einer getrennten Instanz wird dadurch nicht ersetzt.
|
||||
7. Compose-Datei und `.env` einzeln atomar ersetzen. In `.env` wird ausschließlich `FEDEO_VERSION` verändert; `.env.example` und Setup-Skript werden erneuert. Den laufenden Updater ersetzt dieser Vorgang nicht.
|
||||
8. Infrastruktur starten, Bucket-Einrichtung ausführen und Migrationen explizit in einem benannten Einmalcontainer starten. Beim anschließenden regulären Backend-Start läuft dessen bestehende Migrationsprüfung nochmals; bereits angewendete Migrationen werden dabei übersprungen.
|
||||
9. Stack mit `up --wait` starten. Backend-/Frontend-Image-IDs und Healthchecks sowie öffentlich gemeldete Version und Commit prüfen. Erst dann den Release als installiert speichern.
|
||||
|
||||
Status und Phasen werden atomar in `.updates/status.json` und pro Auftrag in `status.json` gespeichert. `events.jsonl` enthält den Verlauf, `commands.log` Fehlermeldungen der Werkzeuge. Das Verzeichnis hat Modus `0700`; Status- und Konfigurationsdateien werden mit `0600` angelegt. Backups und Werkzeugausgaben enthalten vertrauliche Daten und dürfen nicht ungefiltert an eine Oberfläche ausgeliefert werden. Backups werden nicht automatisch gelöscht.
|
||||
|
||||
## Fehler und Wiederherstellung
|
||||
|
||||
- **Download, Konfiguration oder Pull fehlgeschlagen:** Der laufende Stack bleibt bestehen.
|
||||
- **Backup oder Stop fehlgeschlagen:** Der Updater versucht, die zuvor laufenden Container wieder zu starten. Gelingt das nicht, bleibt der Wiederherstellungsstatus gesetzt.
|
||||
- **Ab Austausch der Dateien/Infrastruktur:** Keine automatische Rückkehr zu älteren Images. Bei einem Fehler werden Backend, Frontend und Proxy nach Möglichkeit angehalten. Das Datenbankschema oder das Speicherformat könnten bereits verändert sein.
|
||||
- **Prozess hart beendet oder Host neu gestartet:** `status` erkennt einen zurückgelassenen laufenden Auftrag als `interrupted`. Eine vor Beginn der Wartung gespeicherte Wiederherstellungssperre bleibt erhalten. Abgeschlossene Teiloperationen werden nicht als erfolgreiches Update ausgegeben.
|
||||
|
||||
Zur Diagnose `status` und die geschützten Auftragsdateien lesen. Falls ein benannter `fedeo-update-<Auftrag>`-Migrationscontainer zurückgeblieben ist, dessen Zustand und Logs zuerst prüfen. Er kann unabhängig vom abgebrochenen Compose-Prozess weiterlaufen; erst nach geklärtem Zustand anhalten/entfernen.
|
||||
|
||||
Für die Rückkehr zum alten Stand in einem geplanten Wartungsfenster:
|
||||
|
||||
1. Alle schreibenden Dienste und den Proxy angehalten lassen; keinen neuen Update-Auftrag starten.
|
||||
2. Prüfsummen aus `backup/complete.json` prüfen. Ursprüngliche Compose-Datei, `.env` und gegebenenfalls Override aus `backup/config/` wiederherstellen. `backup/containers.json` dokumentiert die ursprünglichen Image-IDs; insbesondere bewegliche Infrastruktur-Tags vor dem Start auf die gesicherten Image-Stände festlegen.
|
||||
3. Falls Migrationen/Infrastrukturänderungen bereits begonnen haben: PostgreSQL und Dateispeicher aus dem **zusammengehörigen** Backup wiederherstellen. Der PostgreSQL-Dump ist für `pg_restore` geeignet; `globals.sql` enthält Rollen und Kennwörter und muss beim Wiederaufbau der Datenbank berücksichtigt werden. MinIO und Zertifikate bei gestoppten Diensten aus `files.tar` wiederherstellen. Die konkrete Rücksicherung bestehender Daten erfolgt bewusst manuell und ersetzt Daten.
|
||||
4. Wiederhergestellten Stack mit dessen Compose-Dateien starten und Funktionen prüfen. Alternativ den Fehler der Zielversion beheben und diese erfolgreich starten.
|
||||
5. Erst nach erfolgreicher Wiederherstellung die Sperre aufheben:
|
||||
|
||||
```bash
|
||||
sudo python3 /opt/fedeo/scripts/selfhost-update.py resolve --version 3.0.0
|
||||
```
|
||||
|
||||
`resolve` prüft die angegebene Backend-Version, Backend-Erreichbarkeit, Frontend-Erreichbarkeit, laufende Kerndienste, passende Anwendungs-Images und das Fehlen eines zurückgebliebenen Migrationscontainers. Es stellt selbst **keine Daten wieder her**. Bei alten Entwicklungsinstallationen die tatsächlich von `/backend/version` gemeldete Entwicklungsversion angeben. Ein späteres Update kann nach einer manuellen Compose-Wiederherstellung erneut `--accept-compose-replacement` erfordern.
|
||||
|
||||
## Entwicklung und Tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
npm run commits:check
|
||||
```
|
||||
|
||||
Die Update-Tests verwenden den echten Compose-Parser und einen simulierten Docker-Daemon. Sie prüfen u. a. Erfolg, Prüfsummen, Release-Auswahl, unveränderte Konfiguration, Speicherplatz, parallele Aufträge, Backupfehler, Migrationsfehler, falsche laufende Versionen und unterbrochene Aufträge. Ein vollständiger Test mit realem PostgreSQL-/MinIO-Restore auf einer separaten Selfhost-Testinstanz ist vor dem Produktionseinsatz zusätzlich erforderlich.
|
||||
Reference in New Issue
Block a user