Betrieb hinter einem vorhandenen Reverse Proxy

Die Adresse, auf der Docker Port 3000 veroeffentlicht, ist ueber
LERNBAR_ADRESSE in .env einstellbar; Vorgabe bleibt 127.0.0.1. Noetig,
wenn der Reverse Proxy - etwa ein Nginx Proxy Manager - auf einem anderen
Rechner laeuft.

Docker-Ports laufen an ufw vorbei. lernbar-portsperre setzt deshalb in
DOCKER-USER eine Regel, die Port 3000 nur fuer den Proxy oeffnet, und
laesst sich beliebig oft ausfuehren (in einem Debian-13-Container
geprueft). Dazu ein systemd-Dienst, der sie nach Docker setzt.

Abschnitt 6b der Betriebsanleitung beschreibt Einrichtung und Proxy-Host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-10-08 17:35:31 +02:00
co-authored by Claude Opus 5.5
parent 3009c53b5c
commit ead4cdf195
6 changed files with 100 additions and 5 deletions
+17
View File
@@ -26,6 +26,23 @@ Vor `npm version` wandert der Abschnitt „Unveröffentlicht" unter eine neue
## [Unveröffentlicht] ## [Unveröffentlicht]
## [1.1.1] – 2026-10-08
### Hinzugefügt
- **Betrieb hinter einem vorhandenen Reverse Proxy** wie dem Nginx Proxy
Manager: Die Adresse, auf der Docker Port 3000 veröffentlicht, ist über
`LERNBAR_ADRESSE` in `.env` einstellbar (Vorgabe weiterhin `127.0.0.1`)
- `scripts/betrieb/lernbar-portsperre.sh` mit systemd-Dienst – öffnet Port 3000
nur für den Reverse Proxy. Docker-Ports laufen an ufw vorbei, die Regel steht
deshalb in der Kette `DOCKER-USER`
- Abschnitt 6b in `docs/BETRIEB-PROXMOX.md` mit den Einstellungen für den
Proxy-Host
### Geändert
- Die Betriebsanleitung nennt für Docker Compose „2.x oder neuer"
## [1.1.0] – 2026-10-05 ## [1.1.0] – 2026-10-05
Module lassen sich abschalten. Module lassen sich abschalten.
+1
View File
@@ -245,6 +245,7 @@ Protokollzeilen.
| Name | Vorgabe im Container | Bedeutung | | Name | Vorgabe im Container | Bedeutung |
|---|---|---| |---|---|---|
| `LERNBAR_ADRESSE` | `127.0.0.1` | Adresse, auf der Docker Port 3000 veröffentlicht – in `.env` neben `docker-compose.yml`, wenn der Reverse Proxy auf einem anderen Rechner läuft ([Betrieb, 6b](docs/BETRIEB-PROXMOX.md#6b-hinter-einem-vorhandenen-nginx-proxy-manager)) |
| `PORT` | `3000` | Lauschport | | `PORT` | `3000` | Lauschport |
| `TZ` | `Europe/Berlin` | Zeitzone | | `TZ` | `Europe/Berlin` | Zeitzone |
| `LERNBAR_DATEN` | `/daten` | Wurzel für Datenbank und Anhänge | | `LERNBAR_DATEN` | `/daten` | Wurzel für Datenbank und Anhänge |
+6 -2
View File
@@ -15,8 +15,12 @@ services:
# Hinter einem Proxy, der TLS beendet, bleibt das hier http. # Hinter einem Proxy, der TLS beendet, bleibt das hier http.
NODE_ENV: production NODE_ENV: production
ports: ports:
# Nur auf der Schleife lauschen – nach außen geht der Reverse Proxy. # Vorgabe: nur auf der Schleife lauschen, der Reverse Proxy läuft auf
- "127.0.0.1:3000:3000" # derselben Maschine. Steht der Proxy woanders (etwa ein Nginx Proxy
# Manager), in .env die Adresse der VM eintragen:
# LERNBAR_ADRESSE=10.10.13.200
# Docker-Ports laufen an ufw vorbei – siehe docs/BETRIEB-PROXMOX.md.
- "${LERNBAR_ADRESSE:-127.0.0.1}:3000:3000"
volumes: volumes:
- lernbar-daten:/daten - lernbar-daten:/daten
healthcheck: healthcheck:
+50 -3
View File
@@ -2,7 +2,8 @@
Diese Anleitung führt von einer leeren Proxmox-Umgebung zur laufenden Lern-Bar im 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 Betriebsnetz: eine virtuelle Maschine mit Debian, darin Docker mit der Lern-Bar und Caddy
als Reverse Proxy mit HTTPS. Rechne mit etwa zwei Stunden. als Reverse Proxy mit HTTPS – oder, wenn es schon einen Reverse Proxy wie den Nginx Proxy
Manager gibt, dieser (Abschnitt 6b). Rechne mit etwa zwei Stunden.
> **HTTPS ist Pflicht, nicht Kür.** Die Lern-Bar setzt das Anmeldecookie im Betrieb mit dem > **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 > Merkmal `Secure`. Über `http://` nimmt der Browser es nicht an – die Anmeldung scheitert
@@ -17,7 +18,7 @@ als Reverse Proxy mit HTTPS. Rechne mit etwa zwei Stunden.
3. [Grundeinrichtung](#3-grundeinrichtung) 3. [Grundeinrichtung](#3-grundeinrichtung)
4. [Docker installieren](#4-docker-installieren) 4. [Docker installieren](#4-docker-installieren)
5. [Die Lern-Bar holen und starten](#5-die-lern-bar-holen-und-starten) 5. [Die Lern-Bar holen und starten](#5-die-lern-bar-holen-und-starten)
6. [HTTPS mit Caddy](#6-https-mit-caddy) 6. [HTTPS mit Caddy](#6-https-mit-caddy) – oder [6b. hinter einem vorhandenen Nginx Proxy Manager](#6b-hinter-einem-vorhandenen-nginx-proxy-manager)
7. [Das erste Konto](#7-das-erste-konto) 7. [Das erste Konto](#7-das-erste-konto)
8. [Sicherung](#8-sicherung) 8. [Sicherung](#8-sicherung)
9. [Aktualisieren](#9-aktualisieren) 9. [Aktualisieren](#9-aktualisieren)
@@ -97,7 +98,7 @@ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin d
sudo usermod -aG docker "$USER" sudo usermod -aG docker "$USER"
``` ```
Prüfen: `docker compose version` zeigt eine Fassung 2.x. Prüfen: `docker compose version` zeigt eine Fassung 2.x oder neuer.
## 5. Die Lern-Bar holen und starten ## 5. Die Lern-Bar holen und starten
@@ -184,6 +185,52 @@ sudo systemctl reload caddy
> Browser ein Zertifikat, dem das Gerät vertraut. Mit Variante B heißt das: Wurzelzertifikat > Browser ein Zertifikat, dem das Gerät vertraut. Mit Variante B heißt das: Wurzelzertifikat
> auch auf den Diensthandys installieren. > auch auf den Diensthandys installieren.
## 6b. Hinter einem vorhandenen Nginx Proxy Manager
Gibt es im Betrieb schon einen Reverse Proxy, der Zertifikate verwaltet – etwa den
Nginx Proxy Manager –, entfällt Caddy auf der VM. Die Lern-Bar muss dann auf der
Adresse der VM lauschen statt nur auf `127.0.0.1`, damit der Proxy sie erreicht.
**1. Lauschadresse einstellen.** In `/opt/lernbar/.env` (die Datei steht in der
`.gitignore`, `update.sh` lässt sie in Ruhe):
```bash
echo "LERNBAR_ADRESSE=10.10.13.200" > /opt/lernbar/.env # Adresse der VM
cd /opt/lernbar && docker compose up -d
```
**2. Port 3000 nur für den Proxy öffnen.** Ports, die Docker veröffentlicht,
laufen an ufw vorbei – ohne diesen Schritt wäre die Lern-Bar für das ganze Netz
unverschlüsselt erreichbar. Die Regel kommt deshalb in Dockers eigene Kette
`DOCKER-USER`:
```bash
sudo install -m 755 /opt/lernbar/scripts/betrieb/lernbar-portsperre.sh /usr/local/sbin/lernbar-portsperre
sudo install -m 644 /opt/lernbar/scripts/betrieb/lernbar-portsperre.service /etc/systemd/system/
sudo sed -i 's/10.10.13.5/<ADRESSE-DES-NPM>/' /etc/systemd/system/lernbar-portsperre.service
sudo systemctl daemon-reload
sudo systemctl enable --now lernbar-portsperre
sudo iptables -S DOCKER-USER # muss die DROP-Regel mit „! -s <ADRESSE-DES-NPM>" zeigen
```
Prüfen: Vom NPM aus antwortet `curl http://10.10.13.200:3000/api/gesundheit`,
von jedem anderen Rechner läuft derselbe Aufruf ins Leere.
**3. Proxy-Host im Nginx Proxy Manager anlegen:**
| Reiter | Einstellung |
|---|---|
| Details | Domain `lernbar.<eure-domäne>`, Scheme `http`, Forward Hostname `10.10.13.200`, Port `3000`, „Block Common Exploits" an |
| SSL | Zertifikat wählen oder anfordern, „Force SSL" und „HTTP/2 Support" an |
| Advanced | `client_max_body_size 30m;` – sonst scheitern Fotos als Anhang |
Der NPM gibt den Host-Namen der Anfrage unverändert weiter. Das ist wichtig: Next.js
prüft bei jedem Formular, ob Herkunft und Host zusammenpassen, und lehnt das
Absenden sonst ab.
Danach weiter mit Abschnitt 7. Abschnitt 6 (Caddy) entfällt, ebenso die Freigabe
von Port 80 und 443 in ufw auf der VM.
## 7. Das erste Konto ## 7. Das erste Konto
```bash ```bash
@@ -0,0 +1,16 @@
# Öffnet Port 3000 der Lern-Bar nur für den Reverse Proxy.
# Installation siehe docs/BETRIEB-PROXMOX.md, Abschnitt 6b.
# Die Adresse des Proxys in der Zeile ExecStart anpassen.
[Unit]
Description=Lern-Bar: Port 3000 nur für den Reverse Proxy
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/lernbar-portsperre 10.10.13.5
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
# Port 3000 der Lern-Bar nur für den Reverse Proxy öffnen.
# Docker-Ports laufen an ufw vorbei, deshalb die Kette DOCKER-USER, die Docker
# selbst vor seinen eigenen Regeln auswertet und nie überschreibt.
set -eu
PROXY="${1:?Aufruf: lernbar-portsperre <Adresse des Reverse Proxy>}"
REGEL="-p tcp -m conntrack --ctorigdstport 3000 --ctdir ORIGINAL ! -s $PROXY -j DROP"
iptables -N DOCKER-USER 2>/dev/null || true
# shellcheck disable=SC2086
iptables -C DOCKER-USER $REGEL 2>/dev/null || iptables -I DOCKER-USER $REGEL