mirror of
http://100.103.83.12:3003/fegger/pv-agent.git
synced 2026-09-17 15:46:23 +00:00
185 lines
6.0 KiB
Markdown
185 lines
6.0 KiB
Markdown
# 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:27b` und `bge-m3` in dieser Ollama-Instanz;
|
|
- `wissensbasis/` und entweder ein vorhandenes `data/index.db` oder genügend
|
|
Zeit für den initialen Indexaufbau.
|
|
|
|
Das Netz und seine Container/Aliase prüfen:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
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
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Dann `.env` anpassen:
|
|
|
|
1. `PV_API_KEY` durch einen starken zufälligen Wert ersetzen;
|
|
2. optional einen getrennten `PV_ADMIN_API_KEY` setzen;
|
|
3. `OLLAMA_URL` anhand des Netzwerk-Alias prüfen;
|
|
4. `PUID`/`PGID` auf den Besitzer von `data/` setzen.
|
|
|
|
Vor dem ersten Start das gitignored Bind-Mount mit diesen IDs anlegen (Beispiel
|
|
für `1000:1000`):
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
docker compose down
|
|
rm data/index.db
|
|
docker compose up -d
|
|
```
|
|
|
|
## Smoke-Tests
|
|
|
|
```bash
|
|
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 optionales Bewertungsfeedback;
|
|
- Tabelle `comments`: mehrere unabhängige Kommentare pro Antwort;
|
|
- `docker compose logs --follow pv-agent`: dieselben Ereignisse als mit
|
|
`AUDIT ` prä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:
|
|
|
|
```bash
|
|
docker compose exec pv-agent python -m agent.cli audit --limit 20
|
|
```
|
|
|
|
Standardaufbewahrung: 30 Tage; Bereinigung erfolgt beim Öffnen des Audit-Stores.
|
|
Konfiguration:
|
|
|
|
```dotenv
|
|
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, Bewertungsfeedback und Kommentare werden dann nicht gespeichert oder nach stdout
|
|
geschrieben. API-Keys und Authorization-Header werden nie protokolliert.
|
|
|
|
## Sicherheitsprofil
|
|
|
|
- Port `8080` wird nur an die Tailscale-Adresse `100.103.83.12` gebunden.
|
|
- `PV_API_KEY` ist für den Compose-Start verpflichtend.
|
|
- Root-Dateisystem ist read-only; nur `./data` ist schreibbar.
|
|
- Alle Linux-Capabilities werden entfernt; `no-new-privileges` ist 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
|
|
|
|
```bash
|
|
git pull
|
|
docker compose build --pull
|
|
docker compose up -d
|
|
docker image prune
|
|
```
|
|
|
|
Nach Änderungen an der Wissensbasis:
|
|
|
|
```bash
|
|
docker compose run --rm pv-agent python -m agent.cli ingest
|
|
docker compose up -d
|
|
```
|