Files
FEDEO/docs/minio-umstellung-pilot.md

18 KiB

MinIO → SeaweedFS: betreuter Pilot auf einer Installer-Instanz

Stand: 28. September 2026. Dieser Ablauf ergänzt das Austauschkonzept um ausführbare Werkzeuge. Er übernimmt den Speicher einer vorhandenen Installation, beispielsweise 3.3.0, mit unveränderten Anwendungsimages und ohne Datenbankschemamigration.

Vor dem ersten Wartungsfenster nur load-images und plan ausführen. Die Vorprüfung ermittelt die bislang unbekannten Größen und liefert eine kompakte Ausgabe zum gemeinsamen Prüfen. Sie stoppt keine Anwendungscontainer. Die fachliche Abnahme erfolgt zusätzlich auf der konkreten Instanz.

Was der Pilot leistet und wo seine Grenze liegt

  • Vorhandenes MinIO verwenden; kein Abruf von minio/minio oder mc erforderlich.
  • SeaweedFS 4.47 mit dokumentierter FEDEO-Metadatenkorrektur; Offline-Images, SHA-256-geprüftes Paket.
  • Alle Objekte des einzigen FEDEO-Buckets übernehmen, inklusive Exporte und Objekte ohne aktuellen Datenbankverweis. Schlüssel und Metadaten bleiben erhalten.
  • Alle bekannten Schreiber anhalten, ihre automatischen Neustarts sperren, PostgreSQL dumpen und MinIO kalt sichern. Die alten Daten bleiben erhalten.
  • Kopie, vollständigen Inhaltsvergleich und tatsächlichen SeaweedFS-Restore in ein frisches Verzeichnis prüfen. Unbekannte Zielobjekte werden nicht gelöscht.
  • Den S3-Vertrag zusätzlich mit dem tatsächlich installierten Backendimage ausführen. Dabei startet nur das Prüfprogramm, kein FEDEO-Backend.
  • Erst nach diesen Prüfungen den Alias minio exklusiv an SeaweedFS vergeben und die unveränderte Anwendung wieder starten.

Der Pilot ist noch kein neuer Standardinstaller und kein reguläres FEDEO-Release. Ältere Anwendungs-Updater kennen nur MinIO. Ihre Aufträge bleiben nach der Umstellung bewusst über recoveryRequired gesperrt. Dieser Entwicklungsstand enthält den SeaweedFS-Adapter und eine ausdrücklich geprüfte Übergabe über adopt-updater (unten). Diesen Zustand nicht mit dem alten resolve oder durch Löschen der Statusdatei aufheben. Ein alter Installer oder ein altes Release-Compose darf die umgestellte Installation nicht überschreiben.

FEDEO 3.3.0 kann im Systemstatus weiterhin den MinIO-spezifischen Health-Endpunkt abfragen und dadurch den Dateispeicher als gestört anzeigen. Die tatsächliche Funktionsprüfung erfolgt im Pilot über signierte S3-Operationen. Dieser Entwicklungsstand prüft den angemeldeten S3-Bucket auch im Systemstatus; dafür ist anschließend ein Anwendungsrelease mit dieser Änderung erforderlich. Der Speicherwechsel selbst bleibt eine eigene betreute Hostaktion. Der bisherige Standardinstaller wird durch die Migration nicht ersetzt.

Warum das Pilotimage eine gezielte Korrektur enthält

Das unveränderte SeaweedFS 4.47 entfernt beim Speichern den expliziten MIME-Typ application/octet-stream. Bei einem .pdf-Schlüssel liefern HEAD und GET dadurch später application/pdf. Diese Abweichung wurde beim ersten betreuten Versuch durch den strengen Metadatenvergleich erkannt; die Instanz wurde vor Schreibfreigabe erfolgreich auf MinIO zurückgeführt.

scripts/storage/Dockerfile.seaweedfs baut deshalb die feste Herstellerrevision c5073360007d28385a33426a42ac3e4ec504c5a3 mit preserve-s3-content-type.patch als 4.47-fedeo.1. Die Korrektur bewahrt den expliziten Typ für S3-Einträge; die Normalisierung gewöhnlicher Dateisystemeinträge bleibt erhalten. Quellarchiv, Go-Buildimage und Hersteller-Basisimage sind per SHA-256 festgelegt. Gezielte Go-Tests laufen beim Build; das Paket enthält den Buildplan und Patch mit Prüfsummen. Der S3-Vertrag prüft den generischen MIME-Typ zusätzlich mit HEAD, GET und dem Original-Backend-SDK.

Dies ist eine eigene Buildvariante. Bei einem späteren SeaweedFS-Update muss die Korrektur weitergeführt oder durch einen nachgewiesenen Herstellerfix ersetzt werden; das ungeänderte Herstellerimage ist für diese 1:1-Übernahme nicht freigegeben.

Voraussetzungen, die der Plan prüft

Linux amd64, Python ab 3.10, lokaler Docker-Daemon, Docker Compose und tar/du. Die Installation muss laufen und aus dem Installer stammen: lokale Verzeichnisse postgres/ und minio/, interner Endpunkt http://minio:9000, S3-Zugang wie beim Installer aus MINIO_ROOT_*, keine externen Secret-Provider, keine zusätzlichen MinIO-Ports, Datenmounts oder unbekannten Container im internen Netz. Bekannte lokale Matrix-Dienste werden erhalten, während der Kopie angehalten und mit ihren Daten kalt gesichert. Andere Zusatzdienste/Compose-Overrides blockieren den Pilot und benötigen einen angepassten Plan.

Der Plan hält auch vorhandene Container-Healthzustände fest. Bereits vor der Migration als unhealthy bekannte Matrix-Nebendienste müssen beim Wiederanlauf wieder laufen, blockieren aber nicht allein durch denselben Healthfehler die FEDEO-Freigabe. FEDEO-Kerndienste und zuvor gesunde Matrix-Dienste müssen weiterhin ihre Healthchecks bestehen; erforderliche Dienstabhängigkeiten bleiben erhalten. Der Abschlusszustand nennt diese Altfehler unter preexistingUnhealthyServices.

Bereits durch ein früheres Update stillgelegte Matrix-Container dürfen weiterhin zum Compose-Projekt gehören, obwohl sie nicht mehr in dessen Konfiguration stehen. Der Pilot akzeptiert sie nur gestoppt und mit Neustartrichtlinie no, erhält ihre Container und Images und nimmt sie nicht wieder in Compose auf. Ihre lokalen Matrix-Bind-Verzeichnisse werden ebenfalls kalt gesichert. Die alten anonymen Redis-/Coturn-Volumes bleiben unverändert an ihren stillgelegten Containern; sie gehören nicht zum neuen Speicherdienst oder dessen Restore-Test.

Der S3-Prüfer blockiert zusätzliche Buckets, Versionierung einschließlich alter Versionen/Delete-Marker, Object Lock, konfigurierte Serververschlüsselung, Objekt-/Bucket-Tags, eigene Policies/ACLs, Lifecycle, Replikation, Benachrichtigungen, CORS und offene Multipart-Uploads. Unklare S3-Fehler werden nicht als „nicht vorhanden“ gewertet. Datei-/Verzeichniskonflikte und normalisierungsgefährdete Schlüssel wie a//b, a/../b und Verzeichnismarker blockieren ebenfalls.

Die bekannten lokalen MinIO-Metadaten werden zusätzlich geprüft (xl-single, Metadatenformat 3). MinIO kann bei gleichzeitigem a und a/b einen Schlüssel aus der S3-Liste verbergen, obwohl er per GET erreichbar bleibt. Bei gestopptem MinIO muss deshalb die Menge lokaler xl.meta-Objektpfade exakt mit dem S3-Inventar übereinstimmen. Andere Speicherformate oder Abweichungen blockieren die Umschaltung.

Getestete Pilotgrenzen: 200.000 Objekte, höchstens 1 GiB je Objekt. Die Kapazitätsabschätzung berücksichtigt Quellsicherung, neues und wiederhergestelltes Ziel, Metadatenreserve pro Objekt, DB-Dump, Offline-Images, Spool und 5 GiB Reserve. Nach dem Schreibstopp wird das Inventar erneut ermittelt. Es gibt keine Annahme, dass eine unbekannte freie Kapazität ausreichend ist.

Externe Schreiber lassen sich nicht allein anhand von Docker erkennen. Vor migrate --writers-exclusive muss feststehen, dass keine anderen Anwendungen, direkten DB-/S3-Clients oder manuellen Compose-Aufträge parallel schreiben.

Paket erstellen und auf den Host übertragen

Im Entwicklungscheckout mit Docker:

bash scripts/storage/build-pilot.sh

Ergebnis: .release/storage-pilot.tar.gz samt .sha256 und entpacktem Paket. Das Archiv enthält Hostprogramme, Dokumentation und beide benötigten Zielimages. Es enthält keine Instanz-Zugangsdaten, keine Kundendateien und kein neues MinIO. Die Build-Phase darf Images herunterladen; alle Schritte auf dem Zielhost starten Container mit --pull never.

Archiv und Prüfsumme über den üblichen Administrationsweg auf den Docker-Host kopieren. Dort die tatsächliche Prüfsumme mit der mitgelieferten vergleichen, beispielsweise bei Ablage unter /root:

cd /root
sha256sum storage-pilot.tar.gz
tar -xzf storage-pilot.tar.gz
cd storage-pilot
sudo python3 pilot.py load-images
sudo python3 pilot.py plan --directory /opt/fedeo

Die Ausgabe von plan kann in den Supportdialog kopiert werden. Sie enthält Phase, Anwendungsversion, Objektanzahl, Objektbytes und benötigten/verfügbaren Platz; keine Passwörter oder Dateinamen. Falls der Installer in ein anderes Verzeichnis installiert wurde, bei jedem Befehl denselben Pfad angeben.

Ein Plan verändert keine Quelldateien oder fachlichen Daten. Er legt geschützte Migrationsdateien unter .updates/storage-migration/ und einen lokalen Image-Tag zur Aufbewahrung des Hilfsimages an. Die storage/-Datenablage entsteht erst beim Migrationslauf. Das Paket bleibt bis zum Abschluss verfügbar; nicht mitten im Auftrag neu bauen oder austauschen.

Wartungsfenster: kopieren, prüfen, dann freigeben

Erst nach Prüfung der Planausgabe und Abstimmung des Wartungsfensters:

sudo python3 pilot.py migrate --directory /opt/fedeo --writers-exclusive
sudo python3 pilot.py status --directory /opt/fedeo

migrate endet bei phase: verified. Die Anwendung ist dann weiter angehalten. Es hat noch keine fachlichen Schreibzugriffe auf SeaweedFS gegeben. Der Lauf besitzt dieselbe exklusive Sperre wie der Host-Updater.

Die Umschaltung ist ein eigener Befehl:

sudo python3 pilot.py activate --directory /opt/fedeo

activate liest Quelle und Ziel nochmals vollständig, stoppt MinIO, entfernt dessen internen Netzwerkanschluss, sichert SeaweedFS kalt und startet einen separaten Restore-Container mit frisch entpackten Daten. Alle Objekt-Hashes und Metadaten müssen dort stimmen. Danach erhält das aktive Ziel allein den Alias minio, und die S3-Vertragstests laufen erneut, auch mit dem Original-Backend-SDK.

Vor dem Start irgendeines fachlichen Schreibers persistiert das Programm writesReleased: true. Erst danach werden Backend/Hintergrunddienste und zuletzt der öffentliche Proxy gestartet. Ein Fehler beim Neustart führt nicht zu einem automatischen Rückfall auf den nun möglicherweise veralteten Quellspeicher.

Anschließend auf der Instanz prüfen: Anmeldung, bestehender Download, PDF-Vorschau, neuer Upload mit erneutem Download, WebDAV, DATEV/SEPA und Mandantenexport/-import. Bei zwei Testmandanten auch die unveränderten Zugriffsgrenzen kontrollieren. Bereits ausgegebene S3-Links sind zusätzlich über ihren tatsächlichen Zugriffsweg zu prüfen; ein interner Docker-Alias macht interne URLs nicht öffentlich erreichbar.

Fehler und Wiederaufnahme

Zustand Vorgehen
planned Instanz läuft noch; Wartungsfenster vorbereiten.
freezing, backing_up, backed_up, copying, verifying, verified migrate --writers-exclusive setzt fort. Quelle, Schreibstopp, Backups und Inhalte werden erneut geprüft.
cutover, restore_testing activate setzt die noch nicht freigegebene Umschaltung fort; alternativ Rückkehr.
released nach fehlgeschlagenem Start resume-start versucht denselben Zielstand erneut. Keine einfache Rückkehr mehr.
complete SeaweedFS aktiv; alte Daten und Backups weiter aufbewahren.
rolled_back MinIO wieder aktiv. Vor einem neuen Versuch einen neuen betreuten Plan anlegen; bestehende Beweise nicht löschen.

Vor der Schreibfreigabe ist die Rückkehr ausführbar:

sudo python3 pilot.py rollback --directory /opt/fedeo

Sie stoppt das Ziel, stellt Compose, den alten exklusiven Netzwerkanschluss und die ursprünglichen Neustartrichtlinien wieder her und startet die vorher laufenden Container. Quelldaten und DB bleiben unverändert. Nach writesReleased: true verweigert das Programm diesen Befehl. Dann braucht eine Rückkehr eine gesonderte Rückmigration einschließlich Löschungen oder die bewusste Wiederherstellung eines zusammengehörigen Backups.

Protokolle, Sicherungen und Betriebsdaten

status ist die kompakte Ausgabe ohne Geheimnisse. Geschützte Einzelheiten liegen unter /opt/fedeo/.updates/storage-migration/:

  • state.json: Phase, Container-/Image-Identitäten und dauerhafte Schreibgrenze.
  • commands.log, progress.jsonl: Hostfehler und letzter Werkzeugfortschritt.
  • copy/inventory.json, copy/objects.jsonl, copy/verified.json: vollständiges Inventar und überprüfte Objekt-Hashes. Diese Dateien enthalten Dateinamen/Metadaten.
  • backup/database.dump, globals.sql, files.tar, images.tar, complete.json: zusammengehörige Quellsicherung mit Prüfsummen. Der DB-Dump wird mit pg_restore --list geprüft; ein vollständiger fachlicher DB-Restore bleibt eine gesonderte DR-Prüfung.
  • backup/seaweedfs.tar: kalt gesicherter neuer Speicher samt Konfiguration; sein SHA-256 und erfolgreicher echter Restore werden im Zustand festgehalten.

Die neue persistente Ablage ist storage/seaweedfs/, die geschützte Konfiguration storage/config/. SeaweedFS bindet Verwaltung, Filer und Volume-APIs an Loopback im Container; im internen Docker-Netz liegt ausschließlich S3 auf Port 9000. Ein Startwrapper verweigert fehlende oder veränderte Zugangskonfiguration. Die Anwendungsidentität erhält nur Lese-, Schreib- und Listenrechte für ihren Bucket.

Für spätere Sicherungen SeaweedFS anhalten und storage/ vollständig sichern, einschließlich Filer-Metadaten, Masterzustand, Objektdaten, Konfiguration und passendem Image. Die DB-Sicherung muss zum selben Schreibstopp gehören. Die Sicherungen auf demselben Host anschließend auf das vorgesehene externe Backupziel übernehmen. MinIO-Daten, alte Container, Test-Restores und Offline-Images werden vom Pilot nicht automatisch gelöscht.

An den regulären Updater übergeben

Erst nach phase: complete, erfolgreicher Anmeldung und fachlicher Prüfung eines bestehenden Dokuments ausführen. Die Übergabe stoppt keine FEDEO-Container:

sudo python3 pilot.py adopt-updater --directory /opt/fedeo
sudo python3 /usr/local/lib/fedeo-updater/selfhost-update.py check --directory /opt/fedeo

Das neu erstellte Paket enthält die vier zusammengehörigen Updater-Dienstdateien mit Prüfsummen. adopt-updater installiert zuerst diesen Host-Dienst und ruft danach adopt-storage auf. Damit wird die alte Sperre erst nach Installation des passenden Updaters freigegeben. Bereits ausgegebene Pilotarchive bleiben unverändert; für eine schon umgestellte Instanz ein neues geprüftes Paket bereitstellen. Dort nur adopt-updater ausführen, nicht erneut planen, kopieren oder aktivieren. Für diese reine Übergabe ist kein erneutes Laden der Images erforderlich.

Die Übernahme verlangt den abgeschlossenen Migrationszustand einschließlich Schreibfreigabe, vollständigem Kopiernachweis, erfolgreicher S3-Abnahmen und prüfsummengleicher Restore-Sicherung. Compose und .env müssen dem Pilotstand entsprechen. Sie prüft außerdem die tatsächlich laufenden Anwendungsimages, SeaweedFS-Image, lokale Mounts, Konfigurationsdateien und internen S3-Alias sowie das gestoppte und getrennte ursprüngliche MinIO. Ein aktueller Lesezugriff erfolgt mit dem installierten Backend-SDK. Fehler lassen die Updatesperre bestehen.

Danach sind check und apply über den Host-Dienst und die bestehende Oberfläche möglich. Der erste Prüfplan benötigt keine pauschale Compose-Übernahmefreigabe. Der Adapter erhält SeaweedFS samt Konfiguration, Datenpfaden, Zugangsdaten und dem während der Migration festgehaltenen PostgreSQL-Image. Er entfernt die alten MinIO-Dienste aus dem heruntergeladenen Release-Compose, bevor Images geladen werden. Ein Anwendungsupdate lädt oder startet daher weder MinIO noch mc. Ein Wechsel der SeaweedFS- oder PostgreSQL-Version ist ein separater Vorgang.

Vor jeder Datenbankschemamigration prüft das Zielbackend-SDK Schreiben, Lesen, MIME-Erhalt, Streaming, signierte Links, anonymen Zugriffsschutz und Löschen am aktiven Speicher. Ein Fehler hält die Anwendung angehalten und bewahrt den Wiederherstellungszustand. Die normale Anwendungsupdatesicherung enthält storage/, die Speicherbeschreibung und das exakte SeaweedFS-Image. Wiederherstellung und Grenzen stehen in Selfhost-Updates.

Nachgewiesene Tests und ausstehende Freigaben

Der lokale S3-Test verwendet das offizielle MinIO-Release-Binary vom 7. September 2025 und SeaweedFS 4.47 mit der dokumentierten MIME-Korrektur. 1.005 Objekte / 1.073.752.750 Bytes, einschließlich 1-GiB-Grenzdatei, Pagination, Sonderzeichen, Metadaten, leeren Dateien, Streaming, 24-Stunden-Signaturen, fremdem Bucket und ungültigen Zugängen werden geprüft. Beschädigte Zielobjekte werden erkannt und beim Fortsetzen erneut kopiert; der kalte Restore wird vollständig gelesen und verglichen. Testhost: Linux, 16 logische CPUs, rund 29 GiB RAM für Docker, lokaler NVMe-Speicher. Die Laufzeit hängt von Objektanzahl, Datenmenge und Host ab.

Das Hilfs-Lockfile enthält den übernommenen vollständigen SDK-Abhängigkeitsbaum des Backends, nicht nur dieselbe oberste Versionsnummer. Beim Pilot wird außerdem das konkrete installierte Backendimage gegen das Ziel geprüft.

Die Host-Integrationstests verwenden echte Speicher- und PostgreSQL-Container, aber künstliche Anwendungsprozesse. Rückkehr vor Schreibfreigabe sowie vollständige Umschaltung mit Restore und gesperrter Rückkehr nach Schreibfreigabe wurden erfolgreich durchlaufen. Die fachliche Abnahme von FEDEO auf der konkreten Instanz, ein physischer Hostneustart während jeder Phase und die vollständige Wiederherstellung auf einem anderen Host sind damit noch nicht nachgewiesen. Der zusätzliche Test scripts/update/tests/host_storage_integration.py prüft Migration, Updater-Übernahme, zwei Anwendungsupdates und Wiederherstellung aus einer regulären Updatesicherung mit echten Speicher-/Datenbankcontainern und künstlichen Anwendungsimages. Deshalb bleibt der Speicherwechsel ein betreuter Pilot; die allgemeinen Freigabekriterien des Konzepts gelten weiter.