Docker faellt weg. Das Projekt hat keine npm-Abhaengigkeiten und Node fuehrt TypeScript direkt aus - der Container schrieb nur noch drei Programme fest, und dafuer braucht es keine Virtualisierung, sondern einen Ordner. Der Anlass war, dass ADR-0004 zwar `docker compose pull` versprach, es aber nie ein veroeffentlichtes Image gab. Wer installieren wollte, musste whisper.cpp aus dem Quelltext uebersetzen. Plattformschicht (packages/core/src/platform.ts): - Programme werden neben der Anwendung gesucht, nicht im PATH - Daten unter %LOCALAPPDATA%, damit Installation und Update ohne Administratorrechte auskommen - Schriften mitgeliefert: ohne fontsdir setzt libass wortlos eine Ersatzschrift ein - gemessen 720 statt 826 Pixel Zeilenbreite Windows-Eigenheiten, an echtem ffmpeg 8.1 durchprobiert: - Pfade im Filtergraphen brauchen alle drei Schritte (Vorwaertsschraegstriche, escapter Doppelpunkt, Anfuehrungszeichen); je zwei davon reichen nicht - `nice` gibt es nicht, ersetzt durch os.setPriority Auslieferung: - scripts/build-package.ts baut das Paket, laeuft auch unter Linux - install.ps1 ohne Administratorrechte, Autostart ueber den Aufgabenplaner - update legt neue Fassungen bereit; eingespielt wird beim naechsten Start, nie mitten im Stream - ZIP lesen und schreiben ohne Abhaengigkeiten (packages/core/src/zip.ts) Kein `irm ... | iex`-Einzeiler: git.zeasy.dev antwortete instanzweit mit einer Umleitung auf /user/login, und `iex` fuehrte die Anmeldeseite als PowerShell aus. Der Updater verfolgt Umleitungen jetzt nicht und hat keine erfundene Vorgabeadresse mehr. Ausserdem: backup.ps1 war an zwei Stellen dokumentiert, aber nie geschrieben. ADR-0007 ersetzt ADR-0004. 84 Tests, Typpruefung sauber. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AhVSfMFdWnXKCv5JfLnArZ
70 lines
3.5 KiB
Markdown
70 lines
3.5 KiB
Markdown
# ADR-0004: Betrieb in Docker
|
||
|
||
**Status:** ~~akzeptiert~~ **ersetzt durch [ADR-0007](ADR-0007-native-windows.md)** · **Datum:** 2026-09-09
|
||
|
||
> Diese Entscheidung gilt nicht mehr. Das Toolkit laeuft nativ unter Windows.
|
||
> Die Analyse unten bleibt lesenswert - die vier Fallen, die sie beschreibt,
|
||
> waren real, und zwei davon (Pfaduebersetzung, Kopieren ueber die
|
||
> WSL2-Bruecke) sind mit dem Container weggefallen statt geloest worden zu
|
||
> sein. Warum gewechselt wurde, steht in ADR-0007.
|
||
|
||
## Kontext
|
||
|
||
Das Toolkit braucht ffmpeg, ein Whisper-Modell, Node und SQLite. Der Check der
|
||
Zielmaschine ergab: kein ffmpeg, kein pnpm, Python 3.14 (für das
|
||
`ctranslate2` — die Basis von faster-whisper — noch keine verlässlichen Wheels
|
||
liefert), keine NVIDIA-GPU. Das Toolkit soll auf Abdus Stream-PC laufen, also
|
||
auf einem Rechner, dessen Umgebung sich unabhängig vom Projekt ändert.
|
||
|
||
## Entscheidung
|
||
|
||
Alles läuft in Containern, orchestriert über `docker-compose`. Die einzige
|
||
Voraussetzung auf dem Stream-PC ist Docker Desktop und OBS.
|
||
|
||
## Begründung
|
||
|
||
- Die gesamte Toolchain (Node 22, ffmpeg mit libx264/libass, whisper.cpp, das
|
||
Sprachmodell) ist im Image festgeschrieben. Kein "läuft bei mir".
|
||
- Der Python-Konflikt entfällt vollständig, weil kein Python mehr gebraucht
|
||
wird (siehe [ADR-0001](ADR-0001-monorepo-typescript.md), aktualisiert).
|
||
- Updates sind ein `docker compose pull && up -d`, kein Nachinstallieren auf
|
||
einem Rechner, der gerade streamt.
|
||
|
||
## Konsequenzen — die vier Dinge, die man dabei falsch machen kann
|
||
|
||
**1. Die SQLite-Datei gehört nicht in einen Windows-Bind-Mount.**
|
||
Dateisperren über die 9p/virtiofs-Brücke zwischen Windows und WSL2 sind
|
||
unzuverlässig; SQLite im WAL-Modus reagiert darauf mit
|
||
`SQLITE_BUSY`/`database is locked` und im schlimmsten Fall mit Korruption.
|
||
Die Datenbank liegt deshalb in einem **benannten Docker-Volume**
|
||
(`abdulive-db`). Backups werden per Skript aus dem Volume nach Windows
|
||
kopiert, nicht durch direktes Mounten.
|
||
|
||
**2. Große Mediendateien nicht über den Bind-Mount verarbeiten.**
|
||
Das OBS-Replay-Verzeichnis wird nur lesend gemountet. Die Rohdatei wird
|
||
**einmal** in ein containerlokales Volume kopiert, dort verarbeitet, und nur
|
||
das fertige Ergebnis wird zurück nach `data/clips/` geschrieben. Direkt auf
|
||
dem Bind-Mount zu encodieren kostet ein Vielfaches der Zeit.
|
||
|
||
**3. OBS läuft auf dem Host, nicht im Container.**
|
||
Erreichbar über `host.docker.internal:4455`. In `docker-compose.yml` steht
|
||
`extra_hosts: ["host.docker.internal:host-gateway"]`, damit es auch außerhalb
|
||
von Docker Desktop funktioniert.
|
||
|
||
**4. Ein globaler Windows-Hotkey lässt sich aus einem Container nicht abfangen.**
|
||
Deshalb wird gar nicht erst versucht, einen eigenen Hotkey-Dienst zu bauen:
|
||
Der Hotkey wird **in OBS** auf "Wiedergabepuffer speichern" gelegt. OBS meldet
|
||
danach über obs-websocket das Ereignis `ReplayBufferSaved` mit dem Dateipfad —
|
||
das ist der Trigger. Kein Agent auf dem Host, kein zusätzlicher Autostart.
|
||
|
||
**Kosten, ehrlich benannt:** Docker Desktop startet eine WSL2-VM, die im
|
||
Leerlauf ein bis zwei GB RAM belegt und beim Encodieren CPU zieht, die dem
|
||
Stream fehlt. Gegenmaßnahmen: `.wslconfig` mit `memory=4GB` und
|
||
`processors=4`, ffmpeg mit `-preset veryfast` und niedriger Priorität, und
|
||
Rendering standardmäßig **nach** Streamende (`clipper.renderWhileLive: false`),
|
||
sofern die Kandidatenliste erst danach gebraucht wird.
|
||
|
||
**GPU:** Kein NVENC (keine NVIDIA-Karte), und Intel QSV ist aus WSL2 heraus
|
||
nicht verlässlich erreichbar. Es bleibt bei CPU-Encoding mit libx264. Für
|
||
Clips von 30–60 Sekunden ist das unkritisch.
|