Die Abarbeitungsansicht fragte alle zehn Sekunden nach dem Zustand. Jetzt melden vier Datenbank-Trigger `NOTIFY lauf_geaendert, '<laufId>'`, eine LISTEN-Verbindung je Prozess hoert zu, und der Route Handler schiebt weiter. Gemessen: der Haken des Kollegen ist nach 485 ms beim Zuschauer (am Handy 487 ms), vorher bis zu zehn Sekunden. Zwanzig offene Laschen kosten nichts mehr statt zwanzig Abfragen je zehn Sekunden. Das Ereignis kommt aus der Datenbank und nicht aus dem Dienst, aus demselben Grund, aus dem auch die Regeln dort stehen: ein Trigger sieht auch den Seed, eine Migration und die Reparatur per psql. Und NOTIFY erreicht jede Instanz der Anwendung, ohne einen zweiten Dienst. Welche Tabellen melden, haengt an dem, was `laufZustand` liefert — nicht daran, was das Issue vorgeschlagen hat. Mit Triggern nur auf Schrittergebnis und Lauf waere der Strom ein **Rueckschritt** gewesen: das Polling verglich den ganzen Stand und sah deshalb auch Kommentare, ein Strom sieht nur, was gemeldet wird. Der Kommentar des Kollegen waere nie angekommen, und die Seite haette ausgesehen wie immer. Es melden jetzt vier Tabellen, und `laufZustand` traegt `anzahlAnhaenge` — ein Ereignis ohne Entsprechung im Zustand loest nichts aus. Das Polling bleibt als Rueckfall an **derselben** Adresse, unterschieden nur am Accept-Kopf: eine Rechtepruefung, ein Lesemodell, eine Nutzlast. Ein zweiter Endpunkt waere eine zweite Stelle, an der jemand rechtErforderlich vergessen kann. Bei erreichter Obergrenze antwortet der Handler gewoehnlich mit JSON; EventSource meldet darauf einen Fehler und versucht es nicht wieder, also faellt der Client von sich aus zurueck — ohne Sonderfall. Nebenbei zwei Fehler in docs/betrieb/reverse-proxy.md behoben, beide aus #52: `client_max_body_size 8m` bei `ANHANG_MAX_MB=10` haette ein 10-MB-Foto mit 413 abgewiesen, bevor die eigene Meldung zum Zuge kommt. Closes #53 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Laufzettel betreiben
Diese Sammlung richtet sich an den, der Laufzettel betreibt, aber nicht gebaut hat. Sie führt von einem leeren Server bis zur ersten Anmeldung, und danach durch Aktualisierung, Sicherung und Fehlersuche. Wer die Anwendung benutzen will, liest stattdessen die Anleitung.
Es gibt zwei Wege in den Betrieb. Beide sind gleichwertig und führen zum selben Stand.
| Weg | Für wen | Was du mitbringen musst |
|---|---|---|
| Docker Compose | Es gibt schon einen Docker-Host, und weitere Dienste laufen dort ebenso. Aktualisieren heißt neu bauen. | Docker mit Compose-Plugin |
| Nativ im Proxmox-LXC | Es gibt einen Proxmox-Host und keinen Docker. Ein Skript legt den Container an und installiert darin alles — PostgreSQL, Node, die Anwendung, einen systemd-Dienst. | Proxmox VE 8 oder 9, oder ein leeres Debian 13 |
Nimm den Compose-Weg, wenn du schwankst: er ist der Weg, gegen den hier entwickelt und getestet
wird. Der pct-Teil des Proxmox-Skripts ist ungetestet — das steht so, und warum, in
proxmox.md.
Was auf beiden Wegen gilt
Vier Dinge sind keine Empfehlung, sondern Teil des Aufbaus. Sie zu übergehen heißt, einen anderen Stand zu betreiben als den beschriebenen.
Die Datenbank ist von außen nicht erreichbar. Im Compose-Stand hat postgres kein
ports:-Mapping und hängt nur im Netz intern, das internal: true ist — ein Netz ohne Gateway.
Nativ läuft PostgreSQL mit listen_addresses = '', also nur am Unix-Socket. Dieselbe Regel, zwei
Mittel. Daraus folgt, dass jede Sicherung und jeder Blick in die Daten über den Dienstnamen
beziehungsweise den Socket läuft, nie über psql -h localhost. tests/betriebsstand.test.ts hält
das für den Compose-Stand fest, damit ein ports:-Mapping nicht versehentlich zurückkommt.
Die Anwendung bindet auf 127.0.0.1 und spricht kein HTTPS. Davor gehört ein Reverse Proxy, der
das Zertifikat hält — siehe reverse-proxy.md. Ohne Proxy erreicht die
Anwendung niemand außer dem Host selbst, und das ist die richtige Voreinstellung: ein Dienst, der
aus Versehen im LAN steht, fällt keinem auf.
APP_URL ist die öffentliche Adresse und wird nicht geraten. Aus ihr entstehen die QR-Adressen
auf den gedruckten Aufklebern und die OIDC-Rücksprungadresse. Sie später zu ändern ist möglich, aber
teuer — der Grund steht am Anfang von reverse-proxy.md. Leg die Adresse fest,
bevor der erste Aufkleber gedruckt wird.
Geheimnisse entstehen im Zielsystem. APP_SECRET, das Datenbank-Passwort und das erste
Admin-Passwort werden dort erzeugt, wo sie gelten, und stehen in keinem Repository und in keiner
Vorlage. APP_SECRET gehört mit in die Sicherung: ohne ihn sind nach dem Zurückspielen alle
Sitzungen ungültig und die verschlüsselt gespeicherten LDAP-Bind-Passwörter unlesbar. Siehe
sicherung.md.
Die Kapitel
- Inbetriebnahme mit Docker Compose — von null bis zur ersten Anmeldung, mit der vollständigen Tabelle der Umgebungsvariablen, dem Seed und der Aktualisierung
- Der native Weg im Proxmox-LXC —
deploy/proxmox/laufzettel.shunddeploy/install.sh, was sie anlegen, wie ein zweiter Aufruf aktualisiert, und die Prüfliste für den ersten echten Lauf - Reverse Proxy — Caddy und nginx als vollständiges Beispiel, TLS, Weiterleitungen, welche Kopfzeilen nötig sind und welche schaden
- Anmeldung über authentik — OIDC-Provider, Gruppen auf Rollen, Notfallzugang
- Sichern und Zurückspielen — auf beiden Wegen, was in die Sicherung gehört und was nicht, und wie du prüfst, dass das Zurückspielen wirklich funktioniert
Wo sonst noch etwas steht
../../README.md— Kurzfassung für Entwickler, Betriebsmodi, Seed-Inhalt../../.env.example— jede Umgebungsvariable mit Kommentar, zum Kopieren../architektur.md— warum es so gebaut ist; Abschnitt 6 fasst die Betriebsregel zusammen../anleitung/08-fehlerbehebung.md— Fehlermeldungen der Oberfläche. Wer eine Meldung im Browser sieht, ist dort besser bedient als hier