Zwei Wege in den Betrieb und der Abschluss der Abnahme.
Native Installation
deploy/install.sh richtet Debian 13 in neun Schritten ein. PostgreSQL 17 hört nur am Unix-Socket (listen_addresses = ''), der Dienstnutzer hat kein Login, die Geheimnisse entstehen im Zielsystem und liegen 0600 bei root. Die systemd-Unit steckt im Skript, damit der Proxmox-Weg genau eine Datei laden muss.
Die Umgebungsdatei wird nie überschrieben, auch nicht beim Aktualisieren: sonst entstünde ein neues APP_SECRET, alle Sitzungen endeten, und die verschlüsselten LDAP-Bind-Passwörter wären unlesbar. Wer Schalter mitgibt, die deshalb nicht mehr wirken, bekommt eine Warnung statt stillen Gehorsams.
Geprüft: zweimal in debian:13 durchgelaufen, einmal unter echtem systemd 257. ss -ltn zeigt im Container keinen einzigen lauschenden TCP-Port. Der zweite Lauf lässt Daten, APP_SECRET und Datenbankpasswort unverändert — nachgemessen an Zeilenzahlen, einer eingefügten Markierung und der Prüfsumme der Umgebungsdatei.
Proxmox-Einzeiler
deploy/proxmox/laufzettel.sh legt den Container an und ruft install.sh darin auf. Dialog Standard gegen Erweitert, Trockenlauf, Erkennung eines vorhandenen Containers, --aktualisieren.
Das Erstpasswort reist über eine Leihgabe statt über die Ausgabe: install.sh legt es auf Wunsch in eine Datei (0600, root), der Aufrufer liest sie einmal und löscht sie sofort. Die Ausgabe mitzuschneiden hätte das Passwort durch Pipes und Protokolldateien geschleift.
Der pct-Teil ist ungetestet — hier stand kein PVE-Host zur Verfügung. Die Gegenprobe steht als Prüfliste in docs/betrieb/proxmox.md, das Folge-Issue ist #024. Bedingung dafür: der Einzeiler lädt von main, wird also erst nach diesem Merge prüfbar.
Drei Zusagen ohne Deckung, gefunden von der Abnahme
Der Healthcheck des Webdienstes konnte nie bestehen. busybox löst localhost im Container zuerst nach ::1 auf, Next lauscht nur auf IPv4. docker compose ps zeigte web dauerhaft als unhealthy, während die App einwandfrei antwortete; jedes --wait wäre in den Zeitablauf gelaufen. Ein Test hält die Adresse jetzt fest.
Die CI-Pipeline konnte in keinem Job grün werden. Dem Prüf-Job fehlte das LDAP-Testverzeichnis, das pnpm test dort ausdrücklich verlangt; dem E2E-Job fehlte ein gestarteter Server; und shellcheck wurde aufgerufen, ohne installiert zu sein.
Der README nannte Port 5433, die Entwicklungsdatenbank hört auf 5434 — wer dem README folgte, landete auf der Datenbank eines anderen Projekts.
Dazu zwei Compose-Fehler, die schon beim ersten echten Lauf des dokumentierten Wegs auffielen: DATABASE_URL kam aus der .env und zeigte im Container ins Leere, und dem Migrations-Dienst fehlte APP_SECRET, weshalb der dokumentierte Seed-Befehl mitten im Lauf abbrach.
Abnahme
61 Kriterien, 59 abgehakt. Offen bleiben zwei, mit Begründung in docs/abnahme-mvp.md: der echte Proxmox-Lauf (#024) und der Tag selbst, der unmittelbar nach diesem Merge gesetzt wird.
Folge-Issues: #024 Proxmox auf echtem PVE, #025 Healthcheck gibt die rohe Datenbankfehlermeldung heraus, #026 zwei Konventionen präzisieren.
Tore
pnpm lint, pnpm typecheck, pnpm format:pruefen, pnpm pruefe:doku grün. 1131 Vitest-Tests in 51 Dateien grün (+1: der neue Healthcheck-Test). Ende-zu-Ende: 101 Abläufe in INTERN, 97 in DIENSTLEISTUNG, beide vom Abnahme-Agenten gegen eigene Compose-Stände gefahren. shellcheck ohne Befund über beide Skripte, auch ohne Schwellenwert.
Zwei Wege in den Betrieb und der Abschluss der Abnahme.
## Native Installation
`deploy/install.sh` richtet Debian 13 in neun Schritten ein. PostgreSQL 17 hört nur am Unix-Socket (`listen_addresses = ''`), der Dienstnutzer hat kein Login, die Geheimnisse entstehen im Zielsystem und liegen 0600 bei `root`. Die systemd-Unit steckt im Skript, damit der Proxmox-Weg genau eine Datei laden muss.
**Die Umgebungsdatei wird nie überschrieben**, auch nicht beim Aktualisieren: sonst entstünde ein neues `APP_SECRET`, alle Sitzungen endeten, und die verschlüsselten LDAP-Bind-Passwörter wären unlesbar. Wer Schalter mitgibt, die deshalb nicht mehr wirken, bekommt eine Warnung statt stillen Gehorsams.
Geprüft: zweimal in `debian:13` durchgelaufen, einmal unter echtem systemd 257. `ss -ltn` zeigt im Container **keinen einzigen** lauschenden TCP-Port. Der zweite Lauf lässt Daten, `APP_SECRET` und Datenbankpasswort unverändert — nachgemessen an Zeilenzahlen, einer eingefügten Markierung und der Prüfsumme der Umgebungsdatei.
## Proxmox-Einzeiler
`deploy/proxmox/laufzettel.sh` legt den Container an und ruft `install.sh` darin auf. Dialog Standard gegen Erweitert, Trockenlauf, Erkennung eines vorhandenen Containers, `--aktualisieren`.
Das Erstpasswort reist über eine Leihgabe statt über die Ausgabe: `install.sh` legt es auf Wunsch in eine Datei (0600, `root`), der Aufrufer liest sie einmal und löscht sie sofort. Die Ausgabe mitzuschneiden hätte das Passwort durch Pipes und Protokolldateien geschleift.
**Der `pct`-Teil ist ungetestet** — hier stand kein PVE-Host zur Verfügung. Die Gegenprobe steht als Prüfliste in `docs/betrieb/proxmox.md`, das Folge-Issue ist #024. Bedingung dafür: der Einzeiler lädt von `main`, wird also erst nach diesem Merge prüfbar.
## Drei Zusagen ohne Deckung, gefunden von der Abnahme
- **Der Healthcheck des Webdienstes konnte nie bestehen.** busybox löst `localhost` im Container zuerst nach `::1` auf, Next lauscht nur auf IPv4. `docker compose ps` zeigte `web` dauerhaft als `unhealthy`, während die App einwandfrei antwortete; jedes `--wait` wäre in den Zeitablauf gelaufen. Ein Test hält die Adresse jetzt fest.
- **Die CI-Pipeline konnte in keinem Job grün werden.** Dem Prüf-Job fehlte das LDAP-Testverzeichnis, das `pnpm test` dort ausdrücklich verlangt; dem E2E-Job fehlte ein gestarteter Server; und `shellcheck` wurde aufgerufen, ohne installiert zu sein.
- **Der README nannte Port 5433**, die Entwicklungsdatenbank hört auf 5434 — wer dem README folgte, landete auf der Datenbank eines anderen Projekts.
Dazu zwei Compose-Fehler, die schon beim ersten echten Lauf des dokumentierten Wegs auffielen: `DATABASE_URL` kam aus der `.env` und zeigte im Container ins Leere, und dem Migrations-Dienst fehlte `APP_SECRET`, weshalb der dokumentierte Seed-Befehl mitten im Lauf abbrach.
## Abnahme
61 Kriterien, **59 abgehakt**. Offen bleiben zwei, mit Begründung in `docs/abnahme-mvp.md`: der echte Proxmox-Lauf (#024) und der Tag selbst, der unmittelbar nach diesem Merge gesetzt wird.
Folge-Issues: #024 Proxmox auf echtem PVE, #025 Healthcheck gibt die rohe Datenbankfehlermeldung heraus, #026 zwei Konventionen präzisieren.
## Tore
`pnpm lint`, `pnpm typecheck`, `pnpm format:pruefen`, `pnpm pruefe:doku` grün. **1131 Vitest-Tests** in 51 Dateien grün (+1: der neue Healthcheck-Test). Ende-zu-Ende: 101 Abläufe in `INTERN`, 97 in `DIENSTLEISTUNG`, beide vom Abnahme-Agenten gegen eigene Compose-Stände gefahren. `shellcheck` ohne Befund über beide Skripte, auch ohne Schwellenwert.
Closes #19
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Zwei Wege in den Betrieb, beide so weit gefahren, wie es hier moeglich war.
deploy/install.sh richtet Debian 13 in neun Schritten ein: PostgreSQL 17 hoert
nur am Unix-Socket, der Dienstnutzer hat kein Login, die Geheimnisse entstehen
im Zielsystem und liegen 0600 bei root. Die Umgebungsdatei wird nie
ueberschrieben -- auch nicht beim Aktualisieren, sonst enden alle Sitzungen und
die verschluesselten Bind-Passwoerter waeren unlesbar.
deploy/proxmox/laufzettel.sh legt den Container an und ruft install.sh darin
auf. Der pct-Teil ist ungetestet, weil kein PVE-Host zur Verfuegung stand; die
Gegenprobe steht als Pruefliste in docs/betrieb/proxmox.md, das Folge-Issue ist
#024.
Die Abnahme gegen alle 61 Kriterien hat drei Zusagen ohne Deckung gefunden, alle
behoben: der Healthcheck des Webdienstes konnte nie bestehen (busybox loest
localhost nach ::1 auf, Next lauscht nur auf IPv4), die CI-Pipeline konnte in
keinem Job gruen werden (kein LDAP-Dienst, kein gestarteter Server, kein
shellcheck), und der README nannte fuer die Entwicklungsdatenbank den falschen
Port.
Closes#19
Zusammengefuehrt als Squash direkt auf main: d97aebe.
Der Baum dieses Commits ist bitgenau derselbe wie der des Zweigs (277367ddffbe9edcce246a0664dd1b4c7c65a962 auf beiden Seiten) — der Squash hat inhaltlich nichts veraendert. Weil die Pruefsumme des Commits eine andere ist als die der Zweigspitze, erkennt Gitea den Merge nicht von selbst; deshalb wird dieser Pull Request hier von Hand geschlossen.
Issue #19 hat sich ueber Closes #19 selbst geschlossen.
Zusammengefuehrt als Squash direkt auf `main`: d97aebe.
Der Baum dieses Commits ist bitgenau derselbe wie der des Zweigs (`277367ddffbe9edcce246a0664dd1b4c7c65a962` auf beiden Seiten) — der Squash hat inhaltlich nichts veraendert. Weil die Pruefsumme des Commits eine andere ist als die der Zweigspitze, erkennt Gitea den Merge nicht von selbst; deshalb wird dieser Pull Request hier von Hand geschlossen.
Issue #19 hat sich ueber `Closes #19` selbst geschlossen.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Zwei Wege in den Betrieb und der Abschluss der Abnahme.
Native Installation
deploy/install.shrichtet Debian 13 in neun Schritten ein. PostgreSQL 17 hört nur am Unix-Socket (listen_addresses = ''), der Dienstnutzer hat kein Login, die Geheimnisse entstehen im Zielsystem und liegen 0600 beiroot. Die systemd-Unit steckt im Skript, damit der Proxmox-Weg genau eine Datei laden muss.Die Umgebungsdatei wird nie überschrieben, auch nicht beim Aktualisieren: sonst entstünde ein neues
APP_SECRET, alle Sitzungen endeten, und die verschlüsselten LDAP-Bind-Passwörter wären unlesbar. Wer Schalter mitgibt, die deshalb nicht mehr wirken, bekommt eine Warnung statt stillen Gehorsams.Geprüft: zweimal in
debian:13durchgelaufen, einmal unter echtem systemd 257.ss -ltnzeigt im Container keinen einzigen lauschenden TCP-Port. Der zweite Lauf lässt Daten,APP_SECRETund Datenbankpasswort unverändert — nachgemessen an Zeilenzahlen, einer eingefügten Markierung und der Prüfsumme der Umgebungsdatei.Proxmox-Einzeiler
deploy/proxmox/laufzettel.shlegt den Container an und ruftinstall.shdarin auf. Dialog Standard gegen Erweitert, Trockenlauf, Erkennung eines vorhandenen Containers,--aktualisieren.Das Erstpasswort reist über eine Leihgabe statt über die Ausgabe:
install.shlegt es auf Wunsch in eine Datei (0600,root), der Aufrufer liest sie einmal und löscht sie sofort. Die Ausgabe mitzuschneiden hätte das Passwort durch Pipes und Protokolldateien geschleift.Der
pct-Teil ist ungetestet — hier stand kein PVE-Host zur Verfügung. Die Gegenprobe steht als Prüfliste indocs/betrieb/proxmox.md, das Folge-Issue ist #024. Bedingung dafür: der Einzeiler lädt vonmain, wird also erst nach diesem Merge prüfbar.Drei Zusagen ohne Deckung, gefunden von der Abnahme
localhostim Container zuerst nach::1auf, Next lauscht nur auf IPv4.docker compose pszeigtewebdauerhaft alsunhealthy, während die App einwandfrei antwortete; jedes--waitwäre in den Zeitablauf gelaufen. Ein Test hält die Adresse jetzt fest.pnpm testdort ausdrücklich verlangt; dem E2E-Job fehlte ein gestarteter Server; undshellcheckwurde aufgerufen, ohne installiert zu sein.Dazu zwei Compose-Fehler, die schon beim ersten echten Lauf des dokumentierten Wegs auffielen:
DATABASE_URLkam aus der.envund zeigte im Container ins Leere, und dem Migrations-Dienst fehlteAPP_SECRET, weshalb der dokumentierte Seed-Befehl mitten im Lauf abbrach.Abnahme
61 Kriterien, 59 abgehakt. Offen bleiben zwei, mit Begründung in
docs/abnahme-mvp.md: der echte Proxmox-Lauf (#024) und der Tag selbst, der unmittelbar nach diesem Merge gesetzt wird.Folge-Issues: #024 Proxmox auf echtem PVE, #025 Healthcheck gibt die rohe Datenbankfehlermeldung heraus, #026 zwei Konventionen präzisieren.
Tore
pnpm lint,pnpm typecheck,pnpm format:pruefen,pnpm pruefe:dokugrün. 1131 Vitest-Tests in 51 Dateien grün (+1: der neue Healthcheck-Test). Ende-zu-Ende: 101 Abläufe inINTERN, 97 inDIENSTLEISTUNG, beide vom Abnahme-Agenten gegen eigene Compose-Stände gefahren.shellcheckohne Befund über beide Skripte, auch ohne Schwellenwert.Closes #19
🤖 Generated with Claude Code
Zusammengefuehrt als Squash direkt auf
main:d97aebe.Der Baum dieses Commits ist bitgenau derselbe wie der des Zweigs (
277367ddffbe9edcce246a0664dd1b4c7c65a962auf beiden Seiten) — der Squash hat inhaltlich nichts veraendert. Weil die Pruefsumme des Commits eine andere ist als die der Zweigspitze, erkennt Gitea den Merge nicht von selbst; deshalb wird dieser Pull Request hier von Hand geschlossen.Issue #19 hat sich ueber
Closes #19selbst geschlossen.Pull request closed