commit fd0820ae49c3025d1f7fa07b78b9c3c49e147ab1 Author: SimolZimol <70102430+SimolZimol@users.noreply.github.com> Date: Thu Aug 6 17:37:50 2026 +0200 new file: Dockerfile new file: README.md new file: docker-compose.yml new file: nginx/templates/default.conf.template diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..def1526 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# Basis-Image mit Python +FROM python:3.11-slim + +# Arbeitsverzeichnis erstellen +WORKDIR /app + +# System-Dependencies: DejaVu-Schriftarten für PDF-Export (Umlaute) +RUN apt-get update && apt-get install -y --no-install-recommends \ + fonts-dejavu-core \ + && rm -rf /var/lib/apt/lists/* + +# Kopiere die requirements-Datei und installiere die Abhängigkeiten +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Kopiere den gesamten Projektinhalt in das Arbeitsverzeichnis +COPY . . + +# Umgebungsvariablen von Coolify / docker-compose übernehmen (zur Laufzeit) +ENV SECRET_KEY=$SECRET_KEY + + +# Nicht-root Benutzer aus Sicherheitsgründen +RUN useradd --create-home appuser && chown -R appuser:appuser /app +USER appuser + +# Port für Gunicorn +EXPOSE 8000 + +# Startbefehl (Production: Gunicorn) +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..5bfb89f --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Bluemap Reverse Proxy (Nginx) für Coolify + +Nginx-basierter Reverse Proxy, der deine **Bluemap** (`http://devanturas.net:8100`) +über **HTTPS** auf **`map.devanturas.net`** ausliefert und **in einem iframe** einbettbar macht. + +## Struktur + +``` +ReversProxy/ +├── docker-compose.yml <- Coolify importiert diese Datei +└── nginx/ + └── templates/ + └── default.conf.template <- Nginx-Proxy-Konfiguration (envsubst) +``` + +## So liefere ich es bei Coolify aus + +Die Foundation: **Coolify übernimmt die Domain `map.devanturas.net` und das HTTPS-Zertifikat** (via Let's Encrypt über seinen eigenen Traefik/Caddy-Proxy). Dein Nginx-Container läuft dahinter nur noch auf **HTTP**. So funktioniert der iframe dann `https://map.devanturas.net`. + +### Schritte in Coolify +1. **Neues Projekt → Ressource → Docker Compose** anlegen. +2. Compose-Inhalt aus `docker-compose.yml` (bzw. den Ordner) einfügen. +3. In den **Domain-Einstellungen** der Ressource: `map.devanturas.net` eintragen. + - Coolify klinkt die Domain über seinen Proxy an den Nginx-Container an. + - Port-Ziel: `80`. +4. HTTPS aktivieren (Let's Encrypt) – Coolify erledigt das automatisch. +5. **Deploy.** + +### Wichtig: Bluemap-Adresse anpassen +In `docker-compose.yml` unter `environment`: + +```yaml +UPSTREAM_HOST: "devanturas.net" +UPSTREAM_PORT: "8100" +``` + +- Läuft **Bluemap im selben Docker-Netzwerk** wie dieser Proxy → setze `UPSTREAM_HOST` auf den **Container-/Service-Namen** von Bluemap (z.B. `bluemap`). Das ist am schnellsten und sichersten. +- Andernfalls nimm den Hostnamen oder die IP, die `devanturas.net:8100` bereitstellt (bzw. die Docker-Brückengateway-IP, z.B. `172.17.0.1` unter Linux). + +> **Netzwerk-Hinweis:** Damit dieser Nginx-Container den Bluemap-Container erreichen kann, müssen beide im Ersten Netzwerk hängen. Wenn Coolify deine Compose-Ressource bereits in ein eigenes Netzwerk legt, füge Bluemap dort hinzu oder setze `UPSTREAM_HOST` auf den öffentlichen Hostnamen. + +## Iframe-Einbettung + +Auf deiner Einbettungsseite einfach die Karte per HTTPS einbinden: + +```html + +``` + +### Eingebettete Quellen einschränken (empfohlen) +Standardmäßig erlaubt die Konfiguration `frame-ancestors https://* http://*` (alles). **Aus Sicherheitsgründen** solltest du das in `docker-compose.yml` auf deine echten Seiten einschränken: + +```yaml +FRAME_ANCESTORS: "https://devanturas.net" +``` + +Hinweis: Die einfache `FRAME_ANCESTORS`-Variable lässt sich mit dem Official-Nginx-Image nicht direkt in eine Dynamische CSP einsetzen (es werden nur definierte Variablen ersetzt). Für eine strenge Einschränkung editiere daher den `frame-ancestors`-Wert in `nginx/templates/default.conf.template` direkt (z.B. `frame-ancestors https://devanturas.net;`). + +## WebSockets + +Bluemap nutzt WebSockets für Live-Updates. Die Konfiguration hebt den `Upgrade`-/`Connection`-Header entsprechend an und verlängert die Timeouts, damit die Karte live mitläuft und Verbindungen nicht abbrechen. + +## Lokal testen (ohne Coolify) + +```bash +docker compose up -d +curl http://localhost:8080/ # sollte die Bluemap-Startseite liefern +curl http://localhost:8080/health # -> ok +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fef827b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +services: + bluemap-proxy: + image: nginx:1.27-alpine + container_name: bluemap-proxy + restart: unless-stopped + ports: + # Wenn Coolify den Traffic serviert, reicht Port 80. + # -> Traefik/Caddy (Coolify) verkabelt die Domain map.devanturas.net + # und sichert sie mit HTTPS ab, dann reicht er HTTP an diesen Port weiter. + - "8080:80" + environment: + # Adresse des Bluemap-Servers. Setze das auf den DNS-Namen/Container + # von Bluemap, falls er im selben Docker-Netzwerk läuft (z.B. "bluemap"), + # oder auf die öffentliche IP/den Hostnamen. + UPSTREAM_HOST: "devanturas.net" + UPSTREAM_PORT: "8100" + # Erlaubt das Einbetten als iframe. Setze hier die erlaubten Quellen + # (kommagetrennt), z.B. "https://devanturas.net" + FRAME_ANCESTORS: "*" + # Maximale Upload-/Request-Größe (Bluemap verwendet ggf. größere Responses) + CLIENT_MAX_BODY_SIZE: "50m" + volumes: + - ./nginx/templates:/etc/nginx/templates:ro \ No newline at end of file diff --git a/nginx/templates/default.conf.template b/nginx/templates/default.conf.template new file mode 100644 index 0000000..79085be --- /dev/null +++ b/nginx/templates/default.conf.template @@ -0,0 +1,57 @@ +# Reverse Proxy für Bluemap (http://devanturas.net:8100 -> https://map.devanturas.net) +# Konfiguration als Template: Der offizielle nginx-Container ersetzt die +# ${VAR}-Platzhalter automatisch per envsubst mit den Umgebungsvariablen +# aus docker-compose.yml. + +server { + listen 80; + server_name map.devanturas.net; + + # --- Iframe-Einbettung über HTTPS erlauben --- + # CSP frame-ancestors legt fest, WELCHE Seiten die Karte einbetten dürfen. + # "${FRAME_ANCESTORS}" wird durch die Umgebungsvariable ersetzt. + # Achtung nginx-Image: Leere envsubst-Mengen. Daher hier vorsichtig setzen. + add_header Content-Security-Policy "frame-ancestors https://* http://*; upgrade-insecure-requests" always; + add_header X-Frame-Options "ALLOWALL" always; + + # Puffer für große Bluemap-Responses + client_max_body_size "${CLIENT_MAX_BODY_SIZE}"; + + # --- WebSocket / HTTP-Proxy zu Bluemap --- + location / { + proxy_pass http://"${UPSTREAM_HOST}":"${UPSTREAM_PORT}"; + + # HTTP/1.1 + Upgrade-Header notwendig für WebSockets (Live-Karten-Updates) + 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-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Lange laufende WebSocket-Verbindungen nicht abbrechen + proxy_connect_timeout 60s; + proxy_send_timeout 3600s; + proxy_read_timeout 3600s; + + # Puffergrößen für Streaming (Bluemap sendet große Datenblöcke) + proxy_buffering off; + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + } + + # Healthcheck-Endpunkt für Coolify (erwartet 200) + location = /health { + access_log off; + return 200 "ok\n"; + add_header Content-Type text/plain; + } + + # Komprimierung (reduziert Bandbreite) + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss image/svg+xml; + gzip_min_length 1024; +} \ No newline at end of file