Add reproducible Docker and WireGuard host bootstrap

This commit is contained in:
Mikei386
2026-08-20 21:23:16 +02:00
parent cb07779f5a
commit e83c0e2c70
25 changed files with 1584 additions and 835 deletions
+67 -92
View File
@@ -1,107 +1,82 @@
# Architektur
# Zielarchitektur des neuen KI-Hosts
## Ziel
## Grundsatz
Die Plattform stellt eine private, lokal betriebene OpenAI-kompatible API
bereit. Jede Komponente hat genau eine Aufgabe und kann unabhängig ersetzt
werden. Ein Neuaufbau darf keine Dateien vom alten Host voraussetzen, die nicht
in diesem Repository oder im Modellmanifest beschrieben sind.
Der Host läuft auf Debian 13. Das Betriebssystem darf im Universitätsnetz
administrierbar bleiben; die KI-Plattform wird ausschließlich an die
WireGuard-Adresse gebunden. KI-Container erreichen Heimnetz und Internet über
den Heim-WireGuard-Peer. Bei Tunnelausfall verhindert eine Blackhole-Route den
unbeabsichtigten Rückfall auf das Universitätsgateway.
## Komponenten
```text
Heimnetz / VPN-Clients
|
WireGuard
|
10.77.0.2:8080 Open WebUI
10.77.0.2:8081 Profile Router API
|
Docker-intern
+-- Profile Controller -- Docker Socket (feste Allowlist)
+-- llama-fast --\
+-- llama-medium > exakt einer aktiv
+-- llama-long --/
+-- llama-experimental
+-- SearXNG + Web-MCP
```
| Komponente | Port | Ausführung | Aufgabe |
|---|---:|---|---|
| AI Profile Router | 8081 | systemd, gehärtet | zentrale Client-API und Orchestrierung |
| llama.cpp | 8080 | systemd | Textmodell, Tool Calling und MCP |
| Whisper | 8084, nur localhost | systemd | Speech-to-Text |
| XTTS | 8085, nur localhost | systemd | Text-to-Speech |
| TinySearch | 8000, nur localhost | Docker | kompakte Websuche |
| SearXNG | intern | Docker | Suchmaschinen-Metasuche |
| LLama-GUI | 5240, optional | systemd | manuelle Administration |
| Glances | lokal, optional | systemd | Systemmetriken |
## Container und Vertrauensgrenzen
## Request-Fluss
| Komponente | Außen erreichbar | Aufgabe |
|---|---|---|
| Open WebUI | nur WireGuard, Port 8080 | Chat-Oberfläche |
| Profile Router | nur WireGuard, Port 8081 | OpenAI-API und Profilwahl |
| Profile Controller | nein | startet ausschließlich vier bekannte Profile |
| llama.cpp Profile | nein | Inferenz, Tool Calling, integrierte Vision |
| SearXNG | nein | Websuche für den lokalen Web-MCP |
1. Ein Client verwendet ausschließlich Port 8081.
2. Der Router veröffentlicht `qwen-fast`, `qwen-medium` und `qwen-long`.
3. Passt das aktive Profil nicht zum virtuellen Modell, wird llama.cpp kontrolliert
mit dem passenden Profil neu gestartet.
4. Der Router wartet auf Modellname und erwartete Kontextgröße.
5. Erst dann wird die Anfrage an Port 8080 weitergeleitet.
Profilwahl und Weiterleitung bilden dabei eine atomare Modell-Lease. Ein
zweiter Request kann das Profil nicht mehr zwischen Auswahl und Inferenz
wechseln. Laufende Requests werden vor einem GPU-Hotswap vollständig beendet;
bei Überschreiten des Drain-Timeouts wird der Wechsel abgebrochen, nicht der
Chat.
Nur der Profile Controller erhält den Docker-Socket. Der Router erhält weder
Socket noch Shell-Zugriff und kann dem Controller nur `fast`, `medium`, `long`
oder `experimental` übergeben. Die llama-Container laufen ohne UI,
Capabilities und Schreibzugriff auf die Modelldateien.
## Profilprinzip
Die Profile sind vollständige systemd-Overrides. Ein Profilwechsel kopiert die
gewählte Datei atomar auf `override.conf`, lädt systemd neu und startet genau
einen llama.cpp-Dienst neu. Es gibt niemals mehrere Textmodelle gleichzeitig.
Das unabhängige Register `/etc/mike-ai/router-profiles.json` definiert Kontext
und erwarteten Modellalias. Readiness gilt nur, wenn beides exakt passt; eine
abweichende oder fehlende Registry verhindert den Start.
Alle Profile verwenden dasselbe selbst gebaute llama.cpp-Image. Separate,
normalerweise gestoppte Containerdefinitionen halten Parameter wie Kontext,
MTP und CPU-Offload reproduzierbar. Ein Wechsel stoppt das alte Profil und
startet genau einen bereits angelegten Container. Dadurch lassen sich Profile
einzeln verändern oder duplizieren, ohne vier Modelle parallel im VRAM zu
halten.
## GPU-Hotswap
| Profil | Ausgangswert | Zweck |
|---|---:|---|
| fast | 76.800 Kontext, MTP | mindestens ungefähr 80 Token/s anstreben |
| medium | 94.208 Kontext | mehr Kontext ohne CPU-FFN-Offload |
| long | 131.072 Kontext | maximale Nutzbarkeit, CPU-Offload erlaubt |
| experimental | 76.800 Kontext | isolierte Tests ohne Produktion zu ändern |
Vision und Bildgenerierung teilen sich die RTX mit dem Textmodell. Der Router:
Diese Werte sind reproduzierbare Startwerte, keine Garantie. Nach Einbau der
RTX 3060 werden sie auf dem Zielhost erneut gemessen. Die zweite Karte wird
nicht automatisch in die Produktionsprofile aufgenommen.
1. sperrt die GPU-Orchestrierung,
2. merkt sich das aktive Textprofil,
3. stoppt llama.cpp,
4. startet vorübergehend Vision oder FLUX,
5. beendet den Hilfsprozess vollständig,
6. stellt das ursprüngliche Textprofil wieder her,
7. prüft Modell und Kontext vor der Freigabe.
## Netzwerk
Der zuletzt stabile Zustand und temporäre Worker-PIDs werden atomar unter
`/var/lib/mike-ai-profile-router/state.json` festgehalten. Beim Routerstart
werden ausschließlich dort erfasste Prozesse nach zusätzlicher
Kommandozeilenprüfung beendet und das letzte Profil wiederhergestellt.
- Docker-Netze liegen ausschließlich unter `172.30.0.0/16`.
- Open WebUI und Router binden an `AI_BIND_ADDRESS`, die WireGuard-IP.
- Quellrouting schickt KI-Container in Tabelle 51820 über WireGuard.
- Eine Blackhole-Default-Route bleibt als Fail-Closed-Fallback bestehen.
- Firewallregeln gestatten aus dem VPN nur die beiden veröffentlichten Ports.
- Der Host routet weder Universitätsverkehr ins Heimnetz noch Heimverkehr ins
Universitätsnetz.
- Das Heimnetz muss die Rückroute zur WireGuard-Adresse kennen. Soll auch der
Internetzugang der KI über zuhause laufen, braucht der Heim-Peer zusätzlich
IP-Forwarding und NAT ins Heim-WAN.
## Vertrauensgrenzen
## Nicht automatisch installiert
- Port 8081 verlangt einen eigenen API-Key; nur `/health` und `/ready` sind
absichtlich anonym und enthalten keine privaten Daten.
- Der Client-Key wird vor dem lokalen Upstream entfernt.
- Bild-Uploads sind begrenzt. Remote-Bild-URLs sind standardmäßig aus, damit
der Vision-Pfad nicht als Zugriff auf Intranet oder Metadatenendpunkte dient.
- Maximal 16 Requests werden gleichzeitig bearbeitet; weitere erhalten 429.
- Der Dienst benötigt derzeit wegen systemd-Profilwechsel und GPU-Hotswap noch
Root-Rechte. Die systemd-Sandbox begrenzt diese, ersetzt aber keine künftige
Aufteilung in unprivilegierten Proxy und eng begrenzten Root-Helper.
## Verzeichnislayout auf dem Zielhost
```text
/opt/mike-ai/
ai-profile-router/ Routercode und eigenes Venv
llama.cpp/ exakt ein produktiver Build
models/ Modelle nach Manifest
whisper.cpp/ Speech-to-Text Runtime
xtts/ XTTS Runtime und Cache
web-search/ Docker Compose für TinySearch/SearXNG
/etc/mike-ai/
mcp-servers.json lokale, geheime produktive Konfiguration
*.env Credentials, niemals im Git
/etc/systemd/system/
mike-ai-*.service
mike-ai-llama-ui.service.d/
override.conf
profile-fast.conf.disabled
profile-medium.conf.disabled
profile-long.conf.disabled
```
## Nicht Teil der Zielarchitektur
- parallele llama.cpp-Builds
- allgemeiner Shell-MCP im Standardprofil
- doppelte Unraid-MCPs
- RX-spezifische Dienste ohne eingebaute RX
- automatisch startende Benchmark-Dienste
- Modellkopien außerhalb des dokumentierten Modellverzeichnisses
Bildgenerierung, Whisper, TTS sowie Home-Assistant-, ARR- und Unraid-MCPs sind
Erweiterungen. Sie benötigen eigene Modelle, Rechte oder Secrets und bleiben
im sauberen Basissystem deaktiviert. Multimodale Bildanalyse erfolgt direkt
über Qwen plus Projektor. Nicht installierte Worker-Endpunkte antworten klar
mit `feature_disabled`, statt alte systemd-Pfade aufzurufen.