bifroest/docs/lokal-starten.md
2026-10-28 10:34:27 +01:00

161 lines
11 KiB
Markdown

# Lokal starten und Logs ansehen
Diese Anleitung startet Web und Worker im Vordergrund, so dass die Logs direkt im Terminal erscheinen. Die Ersteinrichtung (`.env`, `aiw gen-key`, `aiw migrate`, `aiw seed-demo`) steht in der [README](../README.md#lokal-starten).
## Schnell: Startskript
```bash
scripts/dev.sh --setup # nur beim ersten Mal: .env, Master-Key, Migrationen, Demo-Nutzer
scripts/dev.sh # PostgreSQL, Migrationen, DB-Dienst PostgreSQL, Web (http://127.0.0.1:8765), Worker
scripts/dev.sh --oracle # dazu Oracle-Container und DB-Dienst für Oracle
scripts/dev.sh --port 8000 # anderer Port für Web
scripts/dev.sh --reset # von null, mit Demo-Workspaces (löscht alle lokalen Daten, mit Rückfrage)
```
Alle Logs erscheinen in einem Terminal mit Präfix (`[web]`, `[worker]`, `[postgres]`, `[oracle]`). Am Ende zeigt das Skript URL und Schlüssel der DB-Dienste für die Registrierung als Datenbank-Treiber (siehe [Datenbanken ausprobieren](#datenbanken-ausprobieren)). **Strg+C** stoppt Web, Worker und die DB-Dienste; die Container laufen weiter. Das Skript setzt `AIW_DB_ALLOW_LOCAL` und `AIW_MCP_ALLOW_LOCAL` auf `true`, sofern `.env` nichts anderes sagt. Die einzelnen Schritte von Hand stehen in den folgenden Abschnitten.
## Von null starten
```bash
scripts/dev.sh --reset # mit Rückfrage („ja“ eingeben)
scripts/dev.sh --reset --yes # ohne Rückfrage, z. B. in einem Skript
scripts/dev.sh --reset --oracle # zusätzlich die Oracle-Daten löschen und Oracle starten
```
`--reset` bringt die lokale Umgebung in den Zustand einer frischen Installation mit Demo:
1. **Prüfen:** Läuft auf dem Web-Port noch etwas (Bifröst), bricht das Skript ab. Ohne Terminal und ohne `--yes` bricht es ebenfalls ab, statt auf eine Antwort zu warten.
2. **Löschen:** PostgreSQL-Container und -Volume (`ai-workspace_aiw-postgres18`), also Workspaces, Chats, Nutzer, Modelle, API-Keys, Einstellungen und die Shop-Datenbank der Demo; dazu `data/` (Uploads, Git-Cache, Demo-Repositories) und die Ablagen aus `AIW_UPLOAD_DIR` und `AIW_GIT_CACHE_DIR`, sofern sie im Projekt liegen. Oracle nur mit `--oracle`.
3. **Aufsetzen wie `--setup`:** Container starten, Migrationen, Demo-Nutzer admin (Plattform-Admin), entwicklung, fachbereich, freigabe.
4. **Demo:** DB-Dienst PostgreSQL starten, dann `aiw demo`, also beide Demo-Workspaces samt Shop-Datenbank und registriertem PostgreSQL-Treiber.
5. **Starten:** Web und Worker wie gewohnt.
Was bleibt: `.env` (Master-Key, Demo-Passwort, eigene Einstellungen) und die Docker-Images. Danach fehlt nur das Modell: als `admin` unter *Administration → Modelle und Zugänge* Endpunkt, API-Key und Modell anlegen. Wer auch die `.env` neu will, löscht sie vorher; `--reset` legt sie dann aus `.env.example` an.
Was danach noch einzurichten ist (Modell, Munin, Hugin, Dokumenten-Auslese, Bitbucket, Benachrichtigungen): kurz in der [Checkliste](checkliste.md), ausführlich in [Einrichtung nach dem Start](einrichtung.md).
Nur die Demos neu, alles andere behalten: `uv run aiw demo --reset` (löscht dabei die Chats der Demo-Workspaces).
## 1. Datenbank
```bash
cd /Users/tom/repos/dev/ai-workspace
docker compose up -d # PostgreSQL auf 127.0.0.1:55433
```
Image und Volume stehen in `docker-compose.yml` (PostgreSQL 18.6, Volume `aiw-postgres18` an `/var/lib/postgresql`). Beim Wechsel der Hauptversion starten die alten Daten nicht mit der neuen: lokal `scripts/dev.sh --reset`, oder vorher `pg_dumpall` und danach einspielen.
Nach neuen Migrationen einmal `uv run aiw migrate` ausführen. Fehlt eine Migration, meldet `/ready` den Stand.
## 2. Web (Terminal 1)
```bash
cd /Users/tom/repos/dev/ai-workspace
AIW_MCP_ALLOW_LOCAL=true AIW_DB_ALLOW_LOCAL=true AIW_METRICS_TOKEN=lokal-token-123 \
uv run aiw web --port 8765
```
Die App läuft unter http://127.0.0.1:8765, Anmeldung zum Beispiel mit `admin`.
## 3. Worker (Terminal 2)
```bash
cd /Users/tom/repos/dev/ai-workspace
AIW_MCP_ALLOW_LOCAL=true AIW_DB_ALLOW_LOCAL=true AIW_METRICS_TOKEN=lokal-token-123 \
AIW_WORKER_HTTP_HOST=127.0.0.1 uv run aiw worker
```
Ohne Worker werden Chat-Nachrichten nicht beantwortet. Sie bleiben in der Warteschlange, bis ein Worker läuft.
Mit **Strg+C** stoppst du den jeweiligen Server. Der Worker meldet sich dabei sauber ab.
## Einstellungen
| Variable | Wirkung |
|---|---|
| `AIW_MCP_ALLOW_LOCAL=true` | MCP-Server auf `localhost` erlauben, z. B. Munin lokal |
| `AIW_DB_ALLOW_LOCAL=true` | Datenquellen auf `localhost` erlauben, z. B. `beispiele/demo_shop.sql` |
| `AIW_METRICS_TOKEN=…` | schaltet `/metrics` ein; ohne Token liefert es 404 |
| `AIW_WORKER_HTTP_HOST=127.0.0.1` | Worker-Probes nur lokal statt auf allen Netzwerkschnittstellen |
| `AIW_LOG_FORMAT=json` | JSON-Zeilen wie im Betrieb; ohne die Einstellung lesbarer Text |
| `AIW_LOG_LEVEL=DEBUG` | ausführlichere Logs (Standard `INFO`) |
Die Variablen lassen sich auch dauerhaft in `.env` eintragen. Dann reicht `uv run aiw web --port 8765` bzw. `uv run aiw worker`.
## Logs lesen
Im Textformat sieht eine Zeile so aus:
```
2026-10-22 11:35:29,605 INFO aiw.access: GET /workspaces 200 duration_ms=26 method=GET request_id=4dc14b11fddc40ab route=/workspaces status=200 user_id=1
```
- **Zugriffszeilen (`aiw.access`):** eine je Request mit Route-Muster, Status, Dauer und Nutzer. `/live`, `/ready` und `/metrics` werden nicht geloggt.
- **Worker:** `run_started` und `run_finished` mit Ergebnis und Dauer, `model_call` mit Modell, Tokens und Dauer, `tool_call` mit Tool und Status. Alle Zeilen eines Runs tragen dieselbe `run_id`.
- **Inhalte:** Prompts, Antworten und Abfrageergebnisse stehen nie im Log.
**JSON-Format:** Mit `jq`, falls installiert, wird es lesbar und filterbar:
```bash
AIW_LOG_FORMAT=json AIW_MCP_ALLOW_LOCAL=true AIW_DB_ALLOW_LOCAL=true uv run aiw worker | jq
# nur ein Run:
… | jq 'select(.run_id == "<run-id>")'
```
**Fehler-ID:** Zeigt die Fehlerseite eine Fehler-ID, findest du die passende Zeile über `request_id` im Web-Log.
## Prüfen (Terminal 3)
```bash
curl -s http://127.0.0.1:8765/live # Web lebt
curl -s http://127.0.0.1:8765/ready # Datenbank, Migrationen, Uploads, Master-Key
curl -s http://127.0.0.1:9101/live # Worker-Schleife läuft
curl -s http://127.0.0.1:9101/ready
curl -s -H "Authorization: Bearer lokal-token-123" http://127.0.0.1:8765/metrics | grep ^aiw_
uv run aiw check # Uploads und Master-Key gegen die Datenbank prüfen
```
## Häufige Probleme
- **`Address already in use`:** Ein alter Server läuft noch. Mit `pkill -f "aiw web"` bzw. `pkill -f "aiw worker"` beenden.
- **`/ready` meldet `database: nicht erreichbar`:** Docker läuft nicht oder der Container ist gestoppt, dann `docker compose up -d`.
- **`/ready` meldet einen veralteten Migrationsstand:** `uv run aiw migrate`.
- **Änderungen an Templates erscheinen nicht:** den Web-Server neu starten, oder ihn mit `--reload` starten, dann startet er bei Änderungen selbst neu.
### Absturz mit Exit-Code 132 (VM ohne AVX)
Exit-Code 132 heißt SIGILL: Eine fertig kompilierte Bibliothek nutzt CPU-Befehle, die der Rechner nicht hat. Typisch für VirtualBox auf Windows-Hosts mit aktivem Hyper-V (WSL2, Docker Desktop, Speicher-Integrität): `grep -o -w -E 'avx|avx2' /proc/cpuinfo` liefert nichts. Betroffen ist zuerst `psycopg-binary`.
- **Am Host beheben (empfohlen):** Hyper-V-Nutzung aus (`bcdedit /set hypervisorlaunchtype off`, Speicher-Integrität aus, Neustart), dann `VBoxManage modifyvm "<VM>" --cpu-profile host`. Danach meldet die VM `avx avx2`.
- **In der VM umgehen:** `sudo apt install libpq5` und `PSYCOPG_IMPL=python` in `.env`; `scripts/dev.sh` übernimmt das für Web, Worker und DB-Dienst. Stürzt danach eine andere Bibliothek ab, steht sie im Stack („Fatal Python error“, `scripts/dev.sh` setzt `PYTHONFAULTHANDLER=1`).
## Datenbanken ausprobieren
Datenbanken sind MCP-Verbindungen eines Workspace über einen Datenbank-Treiber, also einen DB-Dienst aus `services/db-mcp`. `scripts/dev.sh` startet den Dienst für PostgreSQL (Port 8791), mit `--oracle` zusätzlich den Oracle-Container (Oracle Database Free, ca. 6 GB, erster Start einige Minuten; Port 55434, Service `FREEPDB1`, Admin `system`/`aiw`) und den Dienst für Oracle (Port 8792). Von Hand: Container mit `docker compose --profile oracle up -d oracle`, Dienste wie in [services/db-mcp/README.md](../services/db-mcp/README.md#lokal-starten-und-testen).
**Einmalig als Plattform-Admin:** unter *Administration → Datenbank-Treiber* je Dienst einen Treiber registrieren:
| Bezeichnung | Kurzname | URL des Dienstes | Schlüssel des Dienstes |
| --- | --- | --- | --- |
| PostgreSQL | `pg` | `http://localhost:8791/mcp` | `dev-schluessel-12345678` |
| Oracle | `ora` | `http://localhost:8792/mcp` | `dev-schluessel-12345678` |
Dann *Tools abrufen* und unter *Administration → Tools* die vier Tools je Treiber einstufen (`list_tables`, `describe_table`, `query`, `check_connection`; Vorschlag: lesend, erlaubt). Alle Datenbanken dieses Typs übernehmen die Einstufung. Der Schlüssel öffnet nur den Dienst; die Zugangsdaten der Datenbank trägt der Workspace ein.
**Demo-Daten** (Schema `shop` bzw. `SHOP` mit Kunden, Produkten, Bestellungen; einmalig):
```bash
psql postgresql://aiw:aiw@127.0.0.1:55433/postgres -c "CREATE DATABASE demo_shop"
psql postgresql://aiw:aiw@127.0.0.1:55433/demo_shop -f beispiele/demo_shop.sql
docker compose exec -T oracle sqlplus -s system/aiw@FREEPDB1 < beispiele/demo_shop_oracle.sql
```
**Im Workspace:** *Einstellungen → MCP-Server → Datenbank hinzufügen*, Datenbanktyp wählen, Kurzname z. B. `shop`, Host `localhost`, Benutzer `shop_leser`, Passwort `shop-leser-demo`, TLS aus. PostgreSQL: Port `55433`, Datenbank `demo_shop`. Oracle: Port `55434`, Datenbank `FREEPDB1`. Beim Speichern testet Bifröst die Verbindung; die Tools heißen dann `shop__query` usw.
Anhalten: `docker compose --profile oracle stop oracle`. Die Daten bleiben im Volume `aiw-oracle`.
## Hugin ausprobieren
Hugin mit Beispieldaten starten: im Repository `hugin` `scripts/demo.sh` (Server auf `http://127.0.0.1:8080`). Den Key der Integration „Softwareverteilung“ (`hi_…`, Tenant `shop`) aus `.demo/keys.txt` nehmen.
In Bifröst als Plattform-Admin unter *Administration → Hugin* den Host `http://127.0.0.1:8080` eintragen (lokal erlaubt, weil `scripts/dev.sh` `AIW_MCP_ALLOW_LOCAL=true` setzt) → „Hugin ist erreichbar“. Optional `AIW_HUGIN_URL=http://127.0.0.1:8080` in `.env`, dann ist die Adresse vorausgefüllt. Als Workspace-Admin unter *Einstellungen → Hugin* den Key eintragen → „ok, Tenant shop“. Danach Pakete wählen (z. B. `pub-release-notiz`), *Abgleichen*, *Übernehmen*. Die Tools `load_skill`, `read_skill_file` und `hugin_feedback` unter *Administration → Tools* einstufen.