Files
ZeasyAlexandClaude Opus 5 5f6301268a Native Windows-Auslieferung statt Container
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
2026-09-09 17:39:26 +02:00

70 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.