diff --git a/README.md b/README.md index bdcf093..2630c7b 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,45 @@ Jede Meldung enthält einen Link auf die Match-Übersicht (`/stream/match/`) Webhook anlegen: Discord-Kanal → Einstellungen → Integrationen → Webhooks → Neuer Webhook, dann die URL kopieren. Welche Ereignisse gemeldet werden, wählt der Admin im Admin-Bereich unter „Discord-Meldungen“. Die Auswahl wird in der Datenbank gespeichert. Die Webhook-URL bleibt in der Konfiguration, weil sie ein Geheimnis ist. Die Schaltfläche „Testmeldung senden“ prüft die Verbindung. +### Hinter einem Reverse-Proxy + +Die Webseite lässt sich hinter einen Reverse-Proxy wie nginx, Caddy oder Traefik stellen, etwa um sie per HTTPS unter einer eigenen Adresse anzubieten. + +- **Eigene (Sub-)Domain, kein Unterpfad.** Die Anwendung nutzt absolute Pfade (`/api`, `/socket.io`, `/stream`, `/admin`). Unter einem Unterpfad wie `example.de/veto/` funktioniert sie nicht. Nimm eine eigene Subdomain, z. B. `veto.example.de`. +- **WebSockets durchreichen.** Die Live-Updates laufen über Socket.IO. Der Proxy muss den `Upgrade`-Header weitergeben, sonst bleibt die Seite bei „Verbinde mit Lobby“ hängen. +- **`.env` anpassen:** + - `PUBLIC_URL=https://veto.example.de`, damit Einladungs- und Stream-Links stimmen + - `TRUST_PROXY=true`, damit die Begrenzung der Anmeldeversuche die echte Client-IP sieht und nicht die des Proxys +- **Nicht über den Proxy:** + - Die CS2-Spielverbindungen laufen per UDP direkt zum Docker-Host. Für Spieler aus dem Internet braucht es dort Portfreigaben und einen GSLT (`CS2_GSLT`). + - Die Logs der CS2-Server können weiter über das LAN kommen. `LOG_RECEIVER_URL` bleibt dann z. B. `http://192.168.178.31:3000`. +- **Vor dem Freigeben absichern:** Öffentlich erreichbar sind dann auch `/admin` und, ohne Schlüssel, die Stream-Übersicht. Setze ein starkes `ADMIN_PASSWORD` und einen `STREAM_KEY`. + +Beispiel für nginx: + +```nginx +server { + listen 443 ssl http2; + server_name veto.example.de; + + ssl_certificate /etc/letsencrypt/live/veto.example.de/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/veto.example.de/privkey.pem; + + location / { + proxy_pass http://192.168.178.31:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 1h; + } +} +``` + +Ein `502 Bad Gateway` vom Proxy heißt, dass er die Anwendung unter `proxy_pass` nicht erreicht: Sie läuft nicht, oder Adresse bzw. Port stimmen nicht. + --- ## Umgebungsvariablen @@ -383,6 +422,7 @@ Alle Variablen mit Standardwerten stehen in [`.env.example`](.env.example). Die | `LOG_DEBUG` | `false` | empfangene Logzeilen im Terminal ausgeben | | `STREAM_KEY` | leer | Schlüssel für die Stream-Übersicht aller Matches (`/stream?key=…`); leer = offen | | `DISCORD_WEBHOOK_URL` | leer | Discord-Webhook für Meldungen zu Veto, Match-Start, Map- und Serienende sowie Serverfehlern; leer = aus | +| `TRUST_PROXY` | `false` | `true`, wenn die Anwendung hinter einem Reverse-Proxy läuft (echte Client-IP für die Begrenzung der Anmeldeversuche) | | `SERIES_AUTO_ADVANCE_SECONDS` | `30` | Wartezeit nach Map-Ende bis zur nächsten Map bzw. zum Abschluss; `-1` = manuell | Benötigte Zugangsdaten für den Echtbetrieb: