Zwei Dinge, die Reichweite bringen sollen, hingen bisher daran, dass jemand vor seinem Rechner sitzt: der Discord-Rollen-Knopf und die Go-Live- Ankuendigung. Beide brauchen nur Internet. Der Schnitt verlaeuft entlang einer Frage: braucht die Aufgabe eine Datei oder ein Programm, das nur auf dem Stream-PC existiert? Hub (LXC) Ingest (Abdus PC) --------- ----------------- Chat, Zuschauerzahlen OBS-Wiedergabepuffer Discord: Knopf und Go-Live !clip, Rendern, Untertitel Overlay-Seiten fuer OBS Beide schreiben in ihre eigene Datenbank. Eine gemeinsame waere eine Netzwerkfreigabe fuer SQLite - der zuverlaessigste bekannte Weg zu einer beschaedigten Datei. Das kostet ADR-0005 seine Hauptbegruendung: "bindet nur auf 127.0.0.1" gilt fuer den Hub nicht mehr. An die Stelle treten ein Passwort mit signiertem Sitzungs-Cookie fuer alles, was ein Mensch bedient, und ein zufaelliger Schluessel in der Adresse fuer die Browser-Sources. Der Schluessel ist kein schoenes Verfahren - er steht in jedem OBS-Profil -, aber eine Browser-Source kann kein Formular ausfuellen und keinen Login durchhalten. `publicUrl` haengt der OAuth-Rueckruf daran. Twitch vergleicht die Redirect-URI zeichengenau, und ein fehlender Schraegstrich sieht im Fehlertext aus wie ein falsches Client-Secret. Die Routen der Einrichtungsseite sind aus ingest/server.ts herausgeloest, weil sie jetzt an zwei Servern haengen. Begruendung und Konsequenzen in ADR-0008. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
101 lines
4.8 KiB
Markdown
101 lines
4.8 KiB
Markdown
# ADR-0008: Geteilter Betrieb - Hub im LXC, Ingest am Stream-PC
|
|
|
|
Datum: 2026-09-17
|
|
Status: akzeptiert
|
|
Berührt: [ADR-0005](ADR-0005-zugangsdaten.md), [ADR-0006](ADR-0006-ein-dach.md),
|
|
[ADR-0007](ADR-0007-native-windows.md)
|
|
|
|
## Kontext
|
|
|
|
Bis hierher lief alles in einem Prozess auf Abdus Rechner (ADR-0007), und
|
|
alles band an `127.0.0.1` (ADR-0005). Das war richtig, solange jede Aufgabe
|
|
etwas mit OBS zu tun hatte.
|
|
|
|
Zwei neue Aufgaben haben damit aber nichts zu tun:
|
|
|
|
- **Der Rollen-Knopf auf Discord.** Er hängt an einer Gateway-Verbindung im
|
|
Ingest-Daemon. Ist Abdus Rechner aus, klickt jemand auf den Knopf und
|
|
bekommt "Interaktion fehlgeschlagen". Ein Knopf, der nur läuft, während
|
|
der Besitzer am Rechner sitzt, ist kein Knopf.
|
|
- **Die Go-Live-Ankündigung.** Sie braucht Twitch und Discord, sonst nichts.
|
|
|
|
Dazu kam das Overlay. Eine Browser-Source in OBS holt ihre Seite über HTTP;
|
|
ob die von `127.0.0.1` kommt oder aus dem Netz, ist ihr gleich.
|
|
|
|
## Entscheidung
|
|
|
|
Das Toolkit läuft ab jetzt an zwei Stellen, mit einem klaren Schnitt:
|
|
|
|
| | Hub (LXC 141, `abdu.dimension47.de`) | Ingest (Abdus PC) |
|
|
|---|---|---|
|
|
| Befehl | `abdulive hub` | `abdulive ingest` |
|
|
| Twitch-Chat lesen und senden | ja | ja |
|
|
| Zuschauerzahlen, Stream-Sitzungen | ja | ja |
|
|
| Discord: Rollen-Knopf, Go-Live | **ja** | nein |
|
|
| Overlay-Seiten ausliefern | **ja** | nein |
|
|
| OBS, Wiedergabepuffer, `!clip` | nein | **ja** |
|
|
| Rendern, Untertitel | nein | **ja** |
|
|
|
|
Der Schnitt verläuft entlang einer einzigen Frage: **braucht die Aufgabe eine
|
|
Datei oder ein Programm, das nur auf dem Stream-PC existiert?** Alles, was mit
|
|
Nein zu beantworten ist, gehört in den Hub.
|
|
|
|
Der Hub ist damit der einzige Teil, der von außen erreichbar ist. Er bindet
|
|
auf `0.0.0.0`, hinter dem vorhandenen Nginx Proxy Manager, und bringt Overlay,
|
|
Einrichtungsseite und OAuth-Rückruf unter einer Adresse zusammen.
|
|
|
|
## Begründung
|
|
|
|
**Warum nicht alles zentral.** Der Wiedergabepuffer von OBS liegt als Datei
|
|
auf Abdus Platte, ffmpeg und whisper arbeiten darauf, und ein Clip ist
|
|
mehrere hundert Megabyte. Das über das Netz zu schieben wäre teurer als es
|
|
bringt, und obs-websocket gehört ohnehin nicht ins Internet.
|
|
|
|
**Warum nicht alles lokal bleiben.** Genau die zwei Dinge, die Reichweite
|
|
bringen sollen - der Ping und der Knopf - sind die, die durchlaufen müssen.
|
|
Sie an den Stream-PC zu hängen heißt, sie an die Verfügbarkeit einer Person zu
|
|
hängen.
|
|
|
|
**Warum zwei Datenbanken und nicht eine.** Beide Seiten schreiben in ihre
|
|
eigene SQLite-Datei. Eine gemeinsame wäre eine Netzwerkfreigabe für SQLite,
|
|
und das ist der zuverlässigste bekannte Weg zu einer beschädigten Datei. Was
|
|
zusammengeführt werden muss, wird später über Ereignisse zusammengeführt, nicht
|
|
über geteilten Dateizugriff.
|
|
|
|
**Warum der Bruch mit ADR-0005 vertretbar ist.** Dort war die Begründung: was
|
|
nur auf `127.0.0.1` hört, ist gegen alles geschützt, was nicht vor dem Rechner
|
|
sitzt. Diese Eigenschaft geht verloren, und der Schutz wandert auf zwei Dinge:
|
|
|
|
- Passwort mit Sitzungs-Cookie für Übersicht, Einrichtung und Status.
|
|
- Ein zufälliger Schlüssel in der Adresse jeder Browser-Source. Er darf nur
|
|
lesen, nie schreiben, und lässt sich auf der Übersichtsseite neu würfeln.
|
|
|
|
Der Schlüssel in der URL ist kein schönes Verfahren. Er steht in jedem
|
|
OBS-Profil und in jedem Screenshot der Einstellungen. Er ist trotzdem der
|
|
richtige: eine Browser-Source kann kein Formular ausfüllen, keinen Login
|
|
durchhalten und keinen zweiten Faktor bedienen. Jedes Verfahren, das mehr
|
|
verlangt, wird spätestens beim ersten Ausfall mitten im Stream abgeschaltet.
|
|
|
|
**Warum die Zugangsdaten trotzdem verschlüsselt neben der Datenbank liegen.**
|
|
Daran ändert sich nichts. Der Hub hat seinen eigenen Speicher, mit eigenem
|
|
Schlüssel, und die Twitch-Apps brauchen jetzt eine zweite Redirect-URI
|
|
(`https://abdu.dimension47.de/callback`) neben der bisherigen.
|
|
|
|
## Konsequenzen
|
|
|
|
- Die Twitch-App braucht eine zweite Redirect-URI. Twitch vergleicht
|
|
zeichengenau; ein fehlender Schrägstrich sieht im Fehlertext aus wie ein
|
|
falsches Client-Secret.
|
|
- Der Discord-Bot darf nur an **einer** Stelle laufen. Laufen Hub und Ingest
|
|
beide mit hinterlegtem Bot-Token, antworten zwei Prozesse auf denselben
|
|
Klick. Auf dem Stream-PC bleibt das Discord-Token deshalb leer.
|
|
- `abdulive ingest` verliert nichts, macht aber weniger. Der Go-Live-Post ist
|
|
dort weiterhin eingebaut - wer nur lokal fährt, hat damit alles an einer
|
|
Stelle, und dort gibt es zusätzlich das OBS-Vorschaubild.
|
|
- Der Hub kennt OBS nicht und kann deshalb keinen Screenshot für die
|
|
Ankündigung machen. Er nimmt Twitchs Vorschaubild. Das ist kurz nach dem
|
|
Start manchmal noch schwarz - der Preis dafür, dass der Post auch dann
|
|
rausgeht, wenn der Daemon am Stream-PC nicht läuft.
|
|
- ADR-0006 ("ein Dach") gilt weiter, aber jetzt je Seite: der Hub hat ein
|
|
Dach, der Stream-PC hat eins.
|