Files
lernbar/docs/BETRIEB-PROXMOX.md
T
Florian WildeandClaude Opus 5.5 76836197b5 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 <noreply@anthropic.com>
2026-10-05 06:33:31 +02:00

10 KiB
Raw Permalink Blame History

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?
  2. Die VM anlegen
  3. Grundeinrichtung
  4. Docker installieren
  5. Die Lern-Bar holen und starten
  6. HTTPS mit Caddy
  7. Das erste Konto
  8. Sicherung
  9. Aktualisieren
  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:

# 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.

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.

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:

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.

sudo apt install -y caddy

/etc/caddy/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
}
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

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:

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

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://<IP>: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