feat(betrieb): native Installation, Proxmox-Einzeiler und Abnahme (#37)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

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
Nummer 38.

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
This commit is contained in:
Florian Wilde
2026-09-27 13:09:14 +02:00
parent fbbb634e56
commit d97aebed95
20 changed files with 3663 additions and 103 deletions
+55
View File
@@ -0,0 +1,55 @@
# #024 Proxmox-Einzeiler auf einem echten PVE-Host gegenprüfen
**Status:** offen
**Im Tracker:** [#38](https://git.wilde-server.de/florian.wilde/Laufzettel/issues/38)
**Meilenstein:** v0.2.0
**Labels:** phase-2, infra
**Geschätzt:** 2 h **Tatsächlich:** –
## Ziel
`deploy/proxmox/laufzettel.sh` ist statisch geprüft und im Trockenlauf durchgelaufen, aber **nie auf
einem Proxmox-Host ausgeführt** — hier stand keiner zur Verfügung. Der Installationsteil
(`deploy/install.sh`) dagegen ist vollständig getestet: in `debian:13` ohne systemd und in einem
privilegierten Container mit echtem systemd 257, inklusive Aktualisierungslauf, `ProtectSystem`,
Sandbox und `/api/gesundheit`.
Ungeprüft ist damit genau die Klammer darum: `pct`, `pveam`, `pvesh` und `whiptail`.
Dieses Issue schließt, wenn der Einzeiler einmal auf einem echten PVE-Host gelaufen ist und die
Prüfliste in [docs/betrieb/proxmox.md](../betrieb/proxmox.md) („Was du beim ersten Lauf selbst
nachprüfen musst“) abgehakt ist. Die Liste ist der Prüfplan, nicht dieses Issue.
## Konkret ungeprüft
- [ ] `pveversion` erkennt PVE 8 und 9 richtig; Abbruch auf einem Nicht-PVE-Rechner
- [ ] `pveam available` / `pveam download` finden die Debian-13-Standardvorlage
- [ ] `pct create` nimmt die zusammengebauten Argumente an (Speicher mit Inhalt `rootdir`,
unprivilegiert, DHCP auf `vmbr0`)
- [ ] Die Ermittlung der nächsten freien CTID über `pvesh` stimmt mit dem, was PVE vergibt
- [ ] Der Container bekommt eine Adresse, und `CT_IP` wird richtig abgelesen — davon hängen `APP_URL`
und der Abschlussbildschirm ab
- [ ] `pct exec … bash -c "<Umgebung> bash /root/laufzettel-install.sh"` übergibt die Variablen so,
wie `install.sh` sie liest (`APP_URL`, `BIND_ADDR`, `LAUFZETTEL_REPO`, `LAUFZETTEL_ZWEIG`,
`LAUFZETTEL_PASSWORT_DATEI`)
- [ ] Das Erstpasswort wird aus `/root/laufzettel-erstpasswort` gelesen **und danach gelöscht**
- [ ] Der `whiptail`-Dialog ist auf einer PVE-Shell bedienbar (Standard und Erweitert)
- [ ] Der zweite Aufruf erkennt den Container am Hostnamen und aktualisiert statt anzulegen
- [ ] `--aktualisieren` bricht ab, wenn es keinen Container `laufzettel` gibt
- [ ] Die Ausgabe von `install.sh` erscheint im Terminal, ohne von einem Spinner überschrieben zu
werden
## Aufgaben
- [ ] Einzeiler auf einem PVE-Host fahren, Prüfliste abhaken
- [ ] Abweichungen als eigene Issues aufnehmen, nicht hier sammeln
- [ ] Nach dem erfolgreichen Lauf den Satz „Der `pct`-Teil ist ungetestet“ in
`docs/betrieb/proxmox.md` durch das Ergebnis ersetzen (PVE-Fassung, Datum)
- [ ] `docs/abnahme-mvp.md` Zeile 11 abhaken
## Akzeptanzkriterien
- [ ] Ein LXC, in dem `systemctl is-active laufzettel` „active“ meldet und `/api/gesundheit`
`status ok` liefert
- [ ] `pct exec <ctid> -- ss -ltn` zeigt keinen Port 5432
- [ ] Zweiter Aufruf: Daten, `APP_SECRET` und Datenbankpasswort unverändert