Plattformgrundlage
solo nutzt SQLite, verschlüsselte lokale Blobs und eingebettete Vektoren, lokale Koordination und integrierten Worker.
team nutzt PostgreSQL, private S3-Blobs, PGVector, Redis und externen Worker. Gemischte Profile werden abgelehnt.
Aktueller Meilenstein
| Bereich | Implementiert | Verbleibend |
|---|---|---|
| Persistenz | SQLite/PostgreSQL, unveränderliche Migrationen, Transaktionen | Neue Domänen an Repositorygrenzen |
| Blobs | Verschlüsseltes Local/S3-Streaming, Ranges, Checksums, Quoten | Anhänge, Avatare und übrige Inline-Binärfelder |
| Vektoren | Verschlüsselte eingebettete Vektoren, PGVector-ACL, sichere Neuindizierung | Gleicher Autoritäts-/Lebenszyklusvertrag |
| Koordination | Local/Redis-Ereignisse, Cache, Leases, Limits, Invalidierung, Gesundheit | Redis nicht autoritativ halten |
| Jobs | SQLite/PostgreSQL-Queues, Ereignisse, Worker, Retry, Cancel, Admin | Idempotenz oder Outbox je Nebenwirkung |
| Betrieb | Gesundheitsgates, signierte Archive, saubere Wiederherstellung | Restore und Multireplikabetrieb je Umgebung üben |
Laufzeitprofile
LIBRE_PLATFORM_MODE=solo ist Standard. Redis allein macht SQLite und lokale Dateien nicht teilbar.
LIBRE_PLATFORM_MODE=team verlangt:
DATABASE_BACKEND=postgresmitDATABASE_URL;BLOB_STORE_BACKEND=s3;VECTOR_STORE_BACKEND=pgvector;COORDINATION_BACKEND=redismitREDIS_URL; undJOB_WORKER_MODE=external.
Fehlt etwas oder wird lokal gemischt, scheitert der Start.
Bestehendes Solo-System migrieren
Alle Anwendungen und Worker stoppen. Nutze globales libre-webui mit libre-webui migrate-postgres, npx --yes libre-webui@latest oder aus Source
npm run migrate:postgres --. Zielumgebung exakt konfigurieren und zuerst analysieren:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode dry-run
Nur auf das leere Ziel anwenden; bei Abbruch dasselbe gechecksummte Journal fortsetzen:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply
# Only after an interrupted apply of this exact source and target:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply --resume
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode validate
Abschluss erst nach relationalen Zeilen, Plugins, Blobs, eingebetteten und Persona-Vektoren in PostgreSQL/S3/PGVector.
ENCRYPTION_KEY muss .encryption_key entsprechen; STORAGE_ENCRYPTION_KEYS braucht aktive und passende legacy-Keys.
Enthaltenes Team-Profil ausführen
cp deploy/team/.env.example /absolute/path/to/libre-team.env
chmod 600 /absolute/path/to/libre-team.env
Alle REPLACE_* ersetzen. PostgreSQL-Passwort URL-sicher erzeugen, z. B. openssl rand -hex 32. Schlüssel müssen exakt
64 Hexzeichen haben. Neu: legacy = ENCRYPTION_KEY; bei Migration beide = Quellschlüssel. Aktiven neuen Key verwenden,
alte bis zur nachgewiesenen Nichtverwendung behalten.
Unterstützt werden POSTGRES_MIGRATION_MODE, POSTGRES_POOL_MAX, PostgreSQL-Timeouts, REDIS_CONNECT_TIMEOUT_MS,
OLLAMA_BASE_URL, OLLAMA_TIMEOUT, OLLAMA_LONG_OPERATION_TIMEOUT, OLLAMA_MAX_CONTEXT. Timeouts 1,000-3,600,000 ms,
Kontext 128-2,097,152 Tokens, langer Timeout nicht kürzer. Ungültiges scheitert vor Zustand. Externe Worker unterstützen
keine node-lokalen Agent-CLI-Binaries oder Codex-OAuth-Dateien; Team erzwingt aus.
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml ps
Standardmäßig kein Docker-Socket und kein Work. Overlay bei jedem Befehl hinzufügen:
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml \
up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml ps
Der interne Socket-Proxy gibt beiden Prozessen nur benötigte APIs, keinen Raw-Socket oder Hostordner. Docker bleibt keine Tenantgrenze, da Container Hostpfade binden können; nutze VM oder separaten/rootless Daemon. Exponiere PostgreSQL, Redis, MinIO nicht. Für Managed-Dienste Helm mit TLS. Readiness erfordert externen Worker.
Persistenz- und Migrationsgrenze
Identität/Autorisierung nutzen asynchrone Repositories. Transaktionscallbacks erhalten eine Unit of Work derselben Verbindung; globales Repository darin wird abgelehnt. SQLite-Migration validiert Schema, nummerierte Namen und Checksums und lehnt neue, unbekannte oder abweichende Ledgers ab. Readiness und Recovery nutzen denselben Vertrag.
Vor zustandsbehafteten Diensten werden SQLite und WAL/SHM in privaten Scratch kopiert. PLATFORM_PREFLIGHT_TMP_DIR braucht
Platz; Docker/Helm montieren Datenträger statt /tmp. Fehlende Altkeys oder verschachtelte Altdaten blockieren vor Neuerstellung.
Schema v4 ergänzt einen keyed Equality-Token für E-Mails. Recovery verlangt Übereinstimmung. Start erlaubt im schmalen Crashfenster
fehlenden Token bei authentifizierter E-Mail oder altem Nicht-Umschlag, damit Backfill endet. Leere Werte werden NULL; Schäden scheitern.
Dienste initialisieren Speicher aus gewählter Persistence. PostgreSQL greift nie auf SQLite-Singleton oder cwd-JSON zurück.
Dauerjobs bleiben treiberneutral: opaque Executor statt better-sqlite3; Tests lehnen native Handles in gemeinsamen Verträgen ab.
Blob- und Vektorspeicher
Galerie/Dokumentquellen nutzen BlobStore; RAG/Persona-Gedächtnis VectorStore. Alte Galeriezeilen werden dual gelesen und
adoptiert. Relationale Metadaten und dauerhafte Referenz sind autoritativ; Anbieter-URLs/S3-Keys nicht. Anhänge/Avatare noch nicht migriert.
Recovery authentifiziert alle Objekte und Vektoren sowie erkennbare Alttexte und Stimmen streng mit ENCRYPTION_KEY; es repariert
nichts. Beschädigung, falsche Keys, nichtkanonische Layouts und Grenzüberschreitung blockieren.
Standards: 250,000 Objekte, 64 GiB verschlüsselte und klare Blobbytes, 250,000 Vektoren, 4 GiB Vektorciphertext und 500 Millionen
Komponenten. RecoveryInventoryOptions kann in Tests ersetzen, CLI sampelt nie. Alttext: eine Million Felder und je 16 GiB.
Verschlüsselte lokale Blobs
BlobStore ist eigentümerbezogen und bietet Streaming, Metadaten, inklusive Ranges und idempotentes Löschen.
LocalEncryptedBlobStore schreibt UUID-Objekte unter ${DATA_DIR}/blobs mit exklusivem Staging, fsync, atomarem Rename,
Verzeichnissen 0700 und Dateien 0600.
Jedes Objekt hat 256-Bit-Datenschlüssel. AES-256-GCM bindet Blob-ID, Eigentümer, Zweck, Chunk und Länge. Keyring umhüllt Keys; Descriptor speichert Größe, SHA-256, Typ, Zeit, Format und Key-ID. Vollreads prüfen SHA-256, Ranges jeden Chunk.
Quoten reservieren vor Streaming und committen nach Sichtbarkeit. SQLite nutzt BEGIN IMMEDIATE, PostgreSQL serialisierbare
Transaktionen/Locks; S3-Metadaten und Quoten committen gemeinsam. Start gleicht abgelaufene Reservierungen/fehlende Blobs ab.
BLOB_QUOTA_BYTES_PER_USER und BLOB_QUOTA_RESERVATION_TTL_MS steuern Grenzen.
BLOB_STORE_BACKEND=s3 nutzt privaten Bucket, opaque Keys, anwendungsverschlüsselte Streams, PostgreSQL-Descriptor, Ranges,
Digests und idempotentes Löschen. Deleting-Zeilen bleiben bis physisch und atomar entfernt; Reconciliation wiederholt und entfernt
alte Waisen. MinIO-Tests decken Repliken, Tenants, Quoten, Streams und injizierte DB-Fehler ab.
Verschlüsselte eingebettete Vektoren
VectorStore verlangt Actor. Datensätze tragen Namespace, opaque Tenant-ID, Eigentümer, Ressource, Modell, Dimensionen,
Version, Revision, Attribute und Grants. SQLite filtert vor Entschlüsselung, isoliert IDs pro Eigentümer und ersetzt Embeddings,
ACLs und Attribute atomar. AES-256-GCM bindet Identität/Modell; abfragbare Metadaten bleiben klar und dürfen keine Secrets enthalten.
VECTOR_STORE_BACKEND=pgvector filtert Namespace, Modell, Dimension, Version, Ressource, Attribute, Eigentümer und Grant in
derselben SQL wie Distanz und LIMIT; globales Nachfiltern ist verboten. Gruppen werden aus aktueller vertrauenswürdiger Mitgliedschaft
aufgelöst; aufruferseitige groupIds ignoriert, daher sofortige Sperre.
Ingestion/Regeneration erfassen unveränderliche Spezifikation aus Aktivierung, Modell, Vektor-/Chunkerversion, Größe, Überlappung, Schwelle. Sie steuert Chunks, relationale Veröffentlichung, Upsert und Query; SQL-Metadaten sind Indexmanifest.
Regeneration hält erneuerbares Dokument-Lease und prüft Zeile/Tombstone vor Veröffentlichung und um Vektoränderung. Löschen während Upsert entfernt Rekreation. Team-Reads mutieren nie. SQLite republiziert nur bei exaktem Manifest unter Lease; busy/superseded nutzt Keywords.
Indizes werden kompensiert in höchstens 1,000er-Batches ersetzt und vollständig paginiert. Maximal 100,000 Chunks; der 100,001. wird vor Embedding dead-letter ohne Retry. Ändere Chunkgröße/Absätze.
Vor-Manifest-Daten können Vektoren ohne Modell/Chunker haben. Erste Semantik rechunkt autoritativen Text und regeneriert unter aktueller Spezifikation/Lease; kopiert nie alte Payload. Anbieter-/Leasefehler lässt Keywords verfügbar.
SQLite-zu-Team scheitert ohne authentifiziertes aktuelles Manifest und exakten Index. Starte Solo mit demselben DATA_DIR und
ENCRYPTION_KEY, wähle Modell, nutze Einstellungen -> Dokumente -> Embeddings regenerieren je Eigentümer und wiederhole Dry-run.
SQLite verschlüsselt Embeddings; PGVector benötigt Zahlen und verschlüsselt die Spalte nicht. Verlange TLS, verschlüsselte Volumes/Backups, Minimalrolle, eingeschränkte Admins und Logs ohne Vektoren. Text, Gedächtnis, Galerie und Descriptor bleiben umhüllt; Attribute nie Secrets.
Speicherverschlüsselungsschlüssel
Während der aktuellen Migrationsphase müssen Bereitstellungen mit einem
versionierten Schlüsselbund einen stabilen 64-stelligen ENCRYPTION_KEY setzen,
denselben Schlüssel unter dem exakten Eintrag legacy in
STORAGE_ENCRYPTION_KEYS aufnehmen und STORAGE_ENCRYPTION_ACTIVE_KEY_ID auf
einen Eintrag setzen. Schreibvorgänge verwenden den aktiven Schlüssel;
Lesevorgänge akzeptieren alle konfigurierten Schlüssel-IDs, um eine stufenweise
Rotation zu ermöglichen. Diese vorübergehende legacy-Anforderung verhindert,
dass der bestehende Verschlüsselungsdienst unabhängig einen anderen Schlüssel
erzeugt. Bewahre alte Schlüssel auf, bis alle Objekte und Vektoren neu geschrieben
oder umhüllt und verifiziert wurden.
Ohne Map wird Umgebungskey als legacy oder ${DATA_DIR}/.encryption_key gelesen. Nur reguläre, nicht symbolische private Datei;
Factory erstellt/ersetzt nie. Konflikte, fehlende, fehlerhafte oder unbekannte Keys scheitern geschlossen.
SQLite-Abfragen budgetieren Kandidaten, Cipherbytes und Dimensionsarbeit vor Rückgabe; Überschreitung verlangt engere Abfrage.
Koordination
Vertrag bietet Ereignisse, ablaufenden Cache, fenced Leases und Fixed-window-Limits. Local nur eine Replik. Redis nutzt getrennte Clients, begrenzte Payloads, Health, Namespaces, atomare Skripte, Owner-Tokens, Ablauf und Fencing; nie lokaler Fallback. Redis ist nicht Wahrheit: Autorisierung, Jobs und Replay bleiben DB. Kritische Arbeit validiert DB-Lease/Fence vor Nebenwirkung.
Dauerhafte Jobs und Ereignisse
SQLite v3 liefert Jobs, Versuche, Streamheads und Ereignisse; idempotentes Enqueue, begrenzte Retries, Cancel, Progress, Heartbeat, Reclaim, Dead-letter und Cursor-Replay. Verschlüsseltes JSON bindet Identität; Referenzen sind opaque.
SQLite v13/PostgreSQL v12 ergänzen (stream_id, subject_id, global_cursor), filtern vor Catch-up-Limit. Bootstraps registrieren
Dokumentingestion, Medienfortsetzung und Reinigung. Relationale Mutation und Job liegen in derselben Transaktion. Recovery zählt,
authentifiziert und lehnt Head-/Sequenzfehler ab.
Monotone Lease-Tokens fencen alte Worker, garantieren aber nicht exactly-once. Handler benötigen Anbieter-Idempotenz oder Outbox/Inbox und Autorisierungsprüfung direkt vor Nebenwirkungen. SQLite v4 fügt HMAC-E-Mail-Lookup neben randomisiertem Ciphertext hinzu.
Gesundheit und Wiederherstellung
/healthund/health/live: Prozess./health/ready: DB, Ledger, schreibbarer Speicher, erforderliche Abhängigkeiten; keine optionalen Anbieter./health/deep: aktueller Admin, SQLite-Integrität außerhalb HTTP-Loop, optionale Anbieter als Warnung.
libre-webui recovery-check --json bzw. npm run recovery:check -- --json meldet Schlüssel, Speicher, Ciphertext, Jobs,
Plugins, Medien, Work, Labels, Checkpoints, Aktivität, Blocker und Ausschlüsse. Es ist ein Gate, keine Sicherung. Siehe
Wiederherstellungsbereitschaft.
Zertifizierter Multireplikabetrieb
Team ist für 3+ App-Repliken plus externen Worker mit PostgreSQL, PGVector, Redis, S3, Secrets und
JOB_WORKER_MODE=external zertifiziert. Helm lehnt unvollständige Topologien ab; Migrationen wählen Advisory-Lock-Leader.
npm run test:team-platform prüft Replikresume, Workertod, Replay, Redis-Ausfall mit SQL, Widerruf, Limits, S3-Löschung und
Tenants. secrets.existingSecret und networkPolicy.enabled härten Pods; Standard ist Non-root, Read-only-Root, keine
Capabilities, seccomp RuntimeDefault, keine Eskalation.
Bekannte verbleibende Umstellungen
Stimmen, Anhänge, Avatare und künftige Binärressourcen brauchen Referenzen, Dual-read/Backfill, Aufbewahrung und Löschtests.
Jeder künftige Embedding-Aufrufer muss Modell, Dimensionen, Version, Revision, Eigentümer, Ressource und Grants durch
VectorStore tragen. Neue lange oder externe Nebenwirkungen brauchen dauerhafte Ressource, Cancel/Retry und transaktionales
Enqueue/Outbox sowie Multireplika- und Sicherungs-/Restore-Tests vor Team-Aktivierung.