6.0 KiB
Docker-Deployment auf 100.103.83.12
Der Compose-Stack betreibt Test-Frontend und FastAPI-Agent gemeinsam. Er startet
keinen zweiten Ollama-Container, sondern verbindet sich mit dem vorhandenen
externen Docker-Netz ollama_default.
Voraussetzungen
Auf dem Zielhost müssen vorhanden sein:
- Docker Engine mit Compose-Plugin;
- das externe Netz
ollama_default; - ein darin erreichbarer Ollama-Container;
- die Modelle
qwen3.8:27bundbge-m3in dieser Ollama-Instanz; wissensbasis/und entweder ein vorhandenesdata/index.dboder genügend Zeit für den initialen Indexaufbau.
Das Netz und seine Container/Aliase prüfen:
docker network inspect ollama_default
Der Compose-Beispielwert nimmt den DNS-Namen ollama und den internen
Ollama-Port 11434 an. Das ist nicht lokal verifiziert, weil das Netz nur
auf dem Zielhost existiert. Falls der Container im Netz anders heißt, muss
OLLAMA_URL in .env entsprechend gesetzt werden, beispielsweise:
OLLAMA_URL=http://tatsaechlicher-containername:11434
Die veröffentlichte Host-Portnummer 11435 ist innerhalb des gemeinsamen
Docker-Netzes normalerweise nicht relevant; Container sprechen den internen
Port des Ollama-Containers an.
Konfiguration
cp .env.example .env
Dann .env anpassen:
PV_API_KEYdurch einen starken zufälligen Wert ersetzen;- optional einen getrennten
PV_ADMIN_API_KEYsetzen; OLLAMA_URLanhand des Netzwerk-Alias prüfen;PUID/PGIDauf den Besitzer vondata/setzen.
Vor dem ersten Start das gitignored Bind-Mount mit diesen IDs anlegen (Beispiel
für 1000:1000):
mkdir -p data
sudo chown 1000:1000 data
Ohne diesen Schritt kann Docker ein fehlendes Verzeichnis als root anlegen;
der absichtlich unprivilegierte Agent könnte dann weder index.db noch
audit.db schreiben.
.env ist gitignored und darf nicht committed werden. Compose verwendet die
Datei nur zur Interpolation der ausdrücklich in compose.yaml aufgelisteten
Variablen; sonstige lokale Secrets werden nicht pauschal in den Container
durchgereicht.
Start und automatischer Index-Bootstrap
docker compose build
docker compose up -d
docker compose ps
docker compose logs --follow pv-agent
Vor dem API-Start führt das Image automatisch python -m agent.bootstrap aus.
Der Bootstrap prüft, ob data/index.db Chunks und vollständige Vektoren für das
konfigurierte Embedding-Modell enthält. Fehlt der Index oder ist er
unvollständig, wird er aus dem read-only eingebundenen wissensbasis/ über
Ollama neu erzeugt. Erst danach startet FastAPI. Schlägt die Einbettung fehl,
beendet sich der Container bewusst mit Fehler, statt einen unvollständigen
Produktionsindex zu verwenden.
Der Index wird absichtlich beim ersten Containerstart, nicht in einem
Dockerfile-RUN erzeugt: Nur zur Laufzeit ist das externe Netz
ollama_default zuverlässig verfügbar, und der Index bleibt als Hostdatenstand
in ./data, statt veraltet im Image zu liegen. Beim ersten Lauf kann der Start
mehrere Minuten dauern; der Healthcheck hat dafür eine Startfrist von 15
Minuten.
Aufruf im Tailscale-Netz:
http://100.103.83.12:8080/
Im Frontend denselben Wert wie PV_API_KEY als Service-Key eingeben.
Der Prozess läuft als PUID:PGID. data/ muss für diese IDs schreibbar sein,
damit Bootstrap, Audit-Log und /v1/reindex funktionieren. Ein manueller,
erzwungener Neuaufbau bleibt möglich:
docker compose down
rm data/index.db
docker compose up -d
Smoke-Tests
curl --fail http://100.103.83.12:8080/v1/health
curl --fail \
-H 'Authorization: Bearer <PV_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{"question":"Wie hoch ist der steuerfreie Tagesgeldsatz?","mode":"knowledge"}' \
http://100.103.83.12:8080/v1/ask
/v1/health muss "status":"ok" liefern. Ein Status degraded bedeutet in
der Regel, dass der Index fehlt oder Ollama unter dem konfigurierten
Container-DNS-Namen nicht erreichbar ist.
Fragen-, Antwort- und Bewertungsprotokoll
Compose aktiviert standardmäßig ein detailliertes Audit:
data/audit.db: persistente SQLite-Datenbank mit Request-ID, Frage, Antwort, Status, Zitaten, Quellen, Konflikten, Suchplan, Modell, Laufzeit und Regenerierungen;- Tabelle
ratings: Daumen hoch/runter plus optionaler Kommentar; docker compose logs --follow pv-agent: dieselben Ereignisse als mitAUDITpräfixierte JSON-Zeilen für die Betriebsdiagnose; Docker rotiert diese Logs bei 50 MB und behält fünf Dateien.
Letzte Einträge strukturiert anzeigen:
docker compose exec pv-agent python -m agent.cli audit --limit 20
Standardaufbewahrung: 30 Tage; Bereinigung erfolgt beim Öffnen des Audit-Stores. Konfiguration:
PV_AUDIT_ENABLED=true
PV_AUDIT_LOG_CONTENT=true
PV_AUDIT_STDOUT=true
PV_AUDIT_RETENTION_DAYS=30
Fragen und Antworten können sensible Freitexte enthalten. Zugriff auf
data/audit.db, Backups und Docker-Logs ist deshalb auf Administratoren zu
beschränken. Mit PV_AUDIT_LOG_CONTENT=false bleiben nur technische Metadaten
und KB-IDs erhalten; Frage, Antwort, Quellenbeschreibungen, Konflikttext,
Suchplan und Bewertungskommentar werden dann nicht gespeichert oder nach stdout
geschrieben. API-Keys und Authorization-Header werden nie protokolliert.
Sicherheitsprofil
- Port
8080wird nur an die Tailscale-Adresse100.103.83.12gebunden. PV_API_KEYist für den Compose-Start verpflichtend.- Root-Dateisystem ist read-only; nur
./dataist schreibbar. - Alle Linux-Capabilities werden entfernt;
no-new-privilegesist aktiv. wissensbasis/wird read-only eingebunden.- Frontend und API sind same-origin; es ist keine CORS-Freigabe nötig.
- Außerhalb des verschlüsselten Tailnets ist TLS vor dem Dienst erforderlich.
Aktualisierung
git pull
docker compose build --pull
docker compose up -d
docker image prune
Nach Änderungen an der Wissensbasis:
docker compose run --rm pv-agent python -m agent.cli ingest
docker compose up -d