From 76836197b56df2ffe1ba947fd877e57bfe1aa9e9 Mon Sep 17 00:00:00 2001 From: Florian Wilde Date: Mon, 5 Oct 2026 06:33:31 +0200 Subject: [PATCH] Anleitung fuer den Betrieb auf Proxmox Von der leeren VM ueber Docker, Caddy mit HTTPS, Deploy-Schluessel, erstes Konto und zweistufige Sicherung bis zur Abnahme vor dem Echtbetrieb. Die Caddy-Konfiguration ist mit caddy validate geprueft. Die README weist jetzt darauf hin, dass HTTPS Pflicht ist: Das Anmeldecookie ist im Betrieb Secure, ueber http:// scheitert die Anmeldung ohne Fehlermeldung. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 30 +++++ README.md | 5 +- docs/BETRIEB-PROXMOX.md | 260 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 docs/BETRIEB-PROXMOX.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 66805a3..6a73d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,36 @@ Vor `npm version` wandert der Abschnitt „Unveröffentlicht" unter eine neue ## [Unveröffentlicht] +## [1.0.5] – 2026-10-05 + +Das zweite Vierteljahr beginnt, mit Blick auf Teil 1 der Abschlussprüfung. +Dazu eine Anleitung für den Betrieb auf Proxmox. + +### Hinzugefügt + +- **Woche 13 · Linux-Grundlagen** – Handouts S6 (Dateisystem und Befehle), S7 + (Benutzer, Gruppen, Dateirechte), S8 (Pakete, systemd, SSH), Praxisaufgabe + 13.1 (Linux-Server einrichten und absichern), Checkliste „Linux-Server + grundlegend einrichten", Lernzielkontrolle +- **Woche 14 · Betrieb und Überwachung** – Handouts S9 (Überwachung und + Schwellwerte), S10 (Protokolle und Zeitsynchronisation), S11 + (Patch-Management), Praxisaufgabe 14.1 (Überwachung für drei Systeme) +- **Woche 15 · Serviceanfragen bearbeiten** – Handouts A10 (Störung, + Serviceanfrage, Problem, Änderung), A11 (Priorisieren und eskalieren), A12 + (Wissensartikel), Praxisaufgabe 15.1 (eine Woche im ersten Level), Checkliste + „Änderung planen und durchführen", Lernzielkontrolle +- **Woche 16 · Vorbereitung auf Teil 1** – Handouts H4 (Ergonomie), H5 (Energie + rechnen, nachhaltig beschaffen und entsorgen), P4 (Pseudocode, Struktogramm, + Schreibtischtest), Praxisaufgabe 16.1 (Arbeitsplätze bewerten), Checkliste + „Bildschirmarbeitsplatz prüfen" und eine **Probeprüfung Teil 1** – 90 + Minuten, 100 Punkte, durchgehende Fallsituation +- 18 Glossareinträge, 36 Merkkarten +- **`docs/BETRIEB-PROXMOX.md`** – von der leeren VM über Docker, Caddy mit + HTTPS, erstes Konto und Sicherung bis zur Abnahme vor dem Echtbetrieb +- Die README weist darauf hin, dass HTTPS Pflicht ist: Über `http://` nimmt der + Browser das Anmeldecookie nicht an, und die Anmeldung scheitert ohne + Fehlermeldung + ## [1.0.4] – 2026-10-04 Vier weitere Wochen Lehrgang – damit steht das erste Vierteljahr. diff --git a/README.md b/README.md index 8a1b797..6124cdc 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Lernplattform-Baukasten, keine Mandanten, keine Cloud. > **Stand:** Alle zehn Bausteine sind fertig – Fassung 1.0.0. > > - [**Anleitung mit Bildschirmfotos**](docs/ANLEITUNG.md) – wie man damit arbeitet +> - [**Betrieb auf Proxmox**](docs/BETRIEB-PROXMOX.md) – von der leeren VM bis zum Echtbetrieb > - [Abnahmeprotokoll](docs/ABNAHME.md) – die Abnahmekriterien, einzeln durchgespielt > - [Änderungsprotokoll](CHANGELOG.md) · [Fahrplan](ROADMAP.md) · > [Entscheidungen](ENTSCHEIDUNGEN.md) @@ -25,7 +26,9 @@ Lernplattform-Baukasten, keine Mandanten, keine Cloud. - **Betrieb:** Docker mit Compose-Erweiterung (Docker 24 oder neuer) - **Entwicklung:** Node.js 22 oder neuer, Git - Ein Reverse Proxy, der TLS beendet (nginx, Caddy, Traefik) – die Anwendung - selbst spricht nur HTTP und lauscht nur auf der Schleife + selbst spricht nur HTTP und lauscht nur auf der Schleife. **HTTPS ist Pflicht:** + Das Anmeldecookie ist im Betrieb als `Secure` gesetzt, über `http://` scheitert + die Anmeldung ohne Fehlermeldung ### Betrieb mit Docker diff --git a/docs/BETRIEB-PROXMOX.md b/docs/BETRIEB-PROXMOX.md new file mode 100644 index 0000000..1db1d55 --- /dev/null +++ b/docs/BETRIEB-PROXMOX.md @@ -0,0 +1,260 @@ +# Lern-Bar auf Proxmox betreiben + +Diese Anleitung führt von einer leeren Proxmox-Umgebung zur laufenden Lern-Bar im +Betriebsnetz: eine virtuelle Maschine mit Debian, darin Docker mit der Lern-Bar und Caddy +als Reverse Proxy mit HTTPS. Rechne mit etwa zwei Stunden. + +> **HTTPS ist Pflicht, nicht Kür.** Die Lern-Bar setzt das Anmeldecookie im Betrieb mit dem +> Merkmal `Secure`. Über `http://` nimmt der Browser es nicht an – die Anmeldung scheitert +> dann ohne Fehlermeldung, man landet einfach wieder auf der Anmeldeseite. + +--- + +## Inhalt + +1. [VM oder LXC?](#1-vm-oder-lxc) +2. [Die VM anlegen](#2-die-vm-anlegen) +3. [Grundeinrichtung](#3-grundeinrichtung) +4. [Docker installieren](#4-docker-installieren) +5. [Die Lern-Bar holen und starten](#5-die-lern-bar-holen-und-starten) +6. [HTTPS mit Caddy](#6-https-mit-caddy) +7. [Das erste Konto](#7-das-erste-konto) +8. [Sicherung](#8-sicherung) +9. [Aktualisieren](#9-aktualisieren) +10. [Abnahme vor dem Echtbetrieb](#10-abnahme-vor-dem-echtbetrieb) + +--- + +## 1. VM oder LXC? + +**Eine VM.** Docker läuft auch in einem LXC-Container, braucht dort aber `nesting` und +`keyctl`, und in unprivilegierten Containern gibt es immer wieder Ärger mit dem +Speichertreiber und den Rechten auf Volumes. Eine VM ist sauber vom Host getrennt, wird von +Proxmox Backup als Ganzes gesichert und verhält sich wie jeder andere Server. Der zusätzliche +Arbeitsspeicher von ein paar hundert Megabyte fällt nicht ins Gewicht. + +## 2. Die VM anlegen + +| Einstellung | Wert | +|---|---| +| Betriebssystem | Debian 13 („trixie"), Netinstall-Abbild | +| Prozessor | 2 Kerne, Typ `host` | +| Arbeitsspeicher | 2 GB (der Bau des Abbilds braucht kurzzeitig mehr als der Betrieb) | +| Festplatte | 32 GB, VirtIO SCSI, auf einem Speicher, der in die Proxmox-Sicherung fällt | +| Netz | VirtIO, im **Server-VLAN** | +| Optionen | QEMU Guest Agent aktivieren | + +Bei der Installation nur **SSH-Server** und **Standard-Systemwerkzeuge** auswählen, keine +grafische Oberfläche. + +Danach: + +- feste IP-Adresse vergeben oder im DHCP reservieren +- DNS-Eintrag anlegen, etwa `lernbar.betrieb.local` – diesen Namen nutzen die Azubis +- in der VM `sudo apt install qemu-guest-agent && sudo systemctl enable --now qemu-guest-agent` + +## 3. Grundeinrichtung + +Die Lern-Bar bringt dafür ihre eigene Checkliste mit: **Checklisten → Linux-Server +grundlegend einrichten** (Woche 13). Kurzfassung: + +```bash +# Persönlicher Benutzer mit sudo, SSH nur mit Schlüssel (Schritte siehe Handout S8) +sudo apt update && sudo apt upgrade -y +sudo apt install -y unattended-upgrades ufw git +sudo dpkg-reconfigure -plow unattended-upgrades + +# Firewall: SSH nur aus dem Verwaltungsnetz, Web für alle im LAN +sudo ufw default deny incoming +sudo ufw allow from 10.10.99.0/24 to any port 22 proto tcp # Verwaltungsnetz anpassen +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +sudo ufw enable +``` + +> **Docker und ufw:** Ports, die Docker veröffentlicht, laufen an ufw vorbei. Bei der +> Lern-Bar ist das unkritisch, weil `docker-compose.yml` Port 3000 nur auf `127.0.0.1` +> veröffentlicht – von außen ist er nicht erreichbar. Wer das ändert, öffnet den Port für +> alle, egal was ufw sagt. + +## 4. Docker installieren + +Aus dem Paketarchiv von Docker, nicht aus Debian – dort fehlt die Compose-Erweiterung in +aktueller Fassung. + +```bash +sudo apt install -y ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ +https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ + | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt update +sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +# Den eigenen Benutzer berechtigen – danach einmal ab- und wieder anmelden +sudo usermod -aG docker "$USER" +``` + +Prüfen: `docker compose version` zeigt eine Fassung 2.x. + +## 5. Die Lern-Bar holen und starten + +Für den Server einen **eigenen Lesezugang** zum Git-Repository anlegen, nicht die eigenen +Zugangsdaten hinterlegen. In Gitea: Repository → Einstellungen → **Deploy-Schlüssel**, einen +SSH-Schlüssel der VM ohne Schreibrecht eintragen. + +```bash +ssh-keygen -t ed25519 -f ~/.ssh/lernbar_deploy -N "" +cat ~/.ssh/lernbar_deploy.pub # als Deploy-Schlüssel in Gitea eintragen + +cat >> ~/.ssh/config <<'EOF' +Host git.wilde-server.de + IdentityFile ~/.ssh/lernbar_deploy +EOF + +sudo mkdir -p /opt/lernbar && sudo chown "$USER": /opt/lernbar +git clone --branch feat/lernbar-erstfassung \ + git@git.wilde-server.de:florian.wilde/lernbar.git /opt/lernbar +``` + +> Solange `main` noch nicht freigegeben ist, läuft der Betrieb vom Zweig +> `feat/lernbar-erstfassung`. Nach der Freigabe einmal `git -C /opt/lernbar checkout main`, +> danach holt `update.sh` von dort. + +Bauen und starten: + +```bash +cd /opt/lernbar +docker compose up -d --build # der erste Bau dauert einige Minuten +curl -s http://127.0.0.1:3000/api/gesundheit +# {"zustand":"in Ordnung"} +``` + +Die Daten liegen im Docker-Volume `lernbar_lernbar-daten`, auf dem Host unter +`/var/lib/docker/volumes/lernbar_lernbar-daten/_data`. + +## 6. HTTPS mit Caddy + +Caddy läuft direkt auf der VM, nimmt die Verbindungen auf 443 an und reicht sie an +`127.0.0.1:3000` weiter. + +```bash +sudo apt install -y caddy +``` + +`/etc/caddy/Caddyfile`: + +```caddyfile +lernbar.betrieb.local { + # Variante A: Zertifikat der eigenen Zertifizierungsstelle (empfohlen) + tls /etc/caddy/lernbar.crt /etc/caddy/lernbar.key + + # Variante B: Caddys eigene Zertifizierungsstelle – siehe unten + # tls internal + + request_body { + max_size 30MB # Fotos als Anhang, die Anwendung selbst begrenzt auf 25 MB + } + + reverse_proxy 127.0.0.1:3000 +} +``` + +```bash +sudo systemctl reload caddy +``` + +**Welches Zertifikat?** + +- **Variante A – eigene Zertifizierungsstelle:** Gibt es im Betrieb eine Zertifizierungsstelle + (etwa die Active-Directory-Zertifikatsdienste), ein Serverzertifikat für + `lernbar.betrieb.local` ausstellen. Die Rechner in der Domäne vertrauen ihr bereits. + Datei und Schlüssel nach `/etc/caddy/` legen, Rechte `640`, Gruppe `caddy`. +- **Variante B – `tls internal`:** Caddy stellt das Zertifikat selbst aus. Damit Browser es + annehmen, muss das Wurzelzertifikat + `/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt` auf allen Geräten als + vertrauenswürdig hinterlegt werden – an Domänenrechnern per Gruppenrichtlinie, an Handys von + Hand. +- **Ist die Lern-Bar aus dem Internet erreichbar** (öffentlicher DNS-Name, Port 443 offen), + holt Caddy ohne `tls`-Zeile selbst ein Zertifikat von Let's Encrypt. + +> Für die **Installation auf dem Handy** (Startbildschirm, Offline-Lernen) verlangen die +> Browser ein Zertifikat, dem das Gerät vertraut. Mit Variante B heißt das: Wurzelzertifikat +> auch auf den Diensthandys installieren. + +## 7. Das erste Konto + +```bash +cd /opt/lernbar +docker compose exec lernbar node werkzeuge/konto.js \ + --name "Vorname Nachname" --email ausbilder@betrieb.de --rolle ausbilder +``` + +Das ausgegebene Passwort notieren, unter `https://lernbar.betrieb.local` anmelden und es unter +**Verwaltung → Eigenes Passwort** ändern. Danach unter **Verwaltung** die Azubikonten anlegen +und im **Wochenplan** die Wochen einplanen. + +Hat das einzige Ausbilderkonto sein Passwort vergessen, setzt derselbe Befehl es neu. + +## 8. Sicherung + +Zwei Ebenen, die sich ergänzen: + +1. **Proxmox sichert die ganze VM**, etwa nächtlich auf Proxmox Backup Server. Damit lässt sich + der ganze Server zurückholen. +2. **Die Lern-Bar sichert ihre Daten selbst** – Datenbank und Anhänge in einem Archiv, das sich + auch auf einem neuen Server einspielen lässt. + +`/etc/cron.d/lernbar-sicherung`: + +```cron +SHELL=/bin/sh +PATH=/usr/local/bin:/usr/bin:/bin + +# 02:30 sichern, 02:45 Archive älter als 30 Tage aufräumen +30 2 * * * root cd /opt/lernbar && docker compose exec -T lernbar /app/werkzeuge/sicherung.sh /daten/sicherungen >> /var/log/lernbar-sicherung.log 2>&1 +45 2 * * * root cd /opt/lernbar && docker compose exec -T lernbar find /daten/sicherungen -name 'lernbar-*.tar.gz' -mtime +30 -delete + +# 03:00 eine Kopie vom Server wegschaffen – Ziel und Zugang anpassen +0 3 * * * root rsync -a /var/lib/docker/volumes/lernbar_lernbar-daten/_data/sicherungen/ sicherung@nas.betrieb.local:/lernbar/ >> /var/log/lernbar-sicherung.log 2>&1 +``` + +Die Uhrzeiten liegen vor der Proxmox-Sicherung, damit das frische Archiv mit in die +VM-Sicherung fällt. + +**Zurückspielen** steht in der [README](../README.md#zurückspielen). Und: Eine Sicherung, die +nie zurückgespielt wurde, ist keine Sicherung. Einmal im Quartal nach der Checkliste +**Wiederherstellung testen** (Woche 8) auf eine Test-VM zurückspielen. + +## 9. Aktualisieren + +```bash +cd /opt/lernbar +./update.sh +``` + +Das Skript sichert, holt den neuen Stand, baut, schaltet um und wartet auf das Lebenszeichen. +Meldet sich die neue Fassung nicht gesund, schaltet es von selbst auf die vorherige zurück. +Neue Inhalte – etwa weitere Wochen – kommen auf demselben Weg, weil sie Teil des Repositorys +sind. Neue Wochen erscheinen danach im Wochenplan unter „noch nicht eingeplant". + +Updates des Systems selbst spielt `unattended-upgrades` ein. Docker und Caddy kommen dabei mit, +weil sie aus Paketquellen installiert sind. + +## 10. Abnahme vor dem Echtbetrieb + +Bevor die Azubis die Adresse bekommen: + +- [ ] Anmeldung über `https://lernbar.betrieb.local` von einem Arbeitsplatz – ohne + Zertifikatswarnung +- [ ] Anmeldung vom Handy, Installation auf dem Startbildschirm +- [ ] Ein Anhang mit 20 MB lässt sich hochladen +- [ ] Ein Berichtsheft-PDF lässt sich herunterladen +- [ ] `http://lernbar.betrieb.local` leitet auf HTTPS um +- [ ] `http://:3000` ist von einem anderen Rechner aus **nicht** erreichbar +- [ ] Sicherung von Hand ausgelöst, Archiv liegt auf dem NAS +- [ ] Die Sicherung auf eine Test-VM zurückgespielt, Konten und Daten sind da +- [ ] `./update.sh` einmal durchgelaufen +- [ ] Die VM erscheint in der Proxmox-Sicherung und in der Überwachung