Files
mpm/docker/nginx/nginx.conf
2026-10-08 21:13:57 +02:00

142 lines
5.4 KiB
Nginx Configuration File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# =============================================================
# MPM – Reverse Proxy (Nginx)
# Master has restricted capabilities; workers run as unprivileged user app.
# - / -> Management-Frontend (SPA, statische Dateien)
# - /api/ -> Management-Backend (127.0.0.1:3000)
# Ab Phase 4 werden hier dynamisch Modul-Routen (/slug) ergänzt.
# =============================================================
worker_processes auto;
user app;
pid /tmp/nginx.pid;
error_log /dev/stderr warn;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
server_tokens off;
sendfile on;
tcp_nopush on;
# Upload-Grenze (z. B. für Modul-ZIP-Pakete ab Phase 3)
client_max_body_size 10m;
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
client_body_temp_path /tmp/nginx/client_body;
proxy_temp_path /tmp/nginx/proxy;
fastcgi_temp_path /tmp/nginx/fastcgi;
uwsgi_temp_path /tmp/nginx/uwsgi;
scgi_temp_path /tmp/nginx/scgi;
upstream platform_backend {
server 127.0.0.1:3000;
}
server {
listen 8080;
server_name _;
root /app/public;
index index.html;
# Sicherheits-Header
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
# Gehashte Frontend-Assets: lange cachen
location /assets/ {
expires 1y;
try_files $uri =404;
}
# Management-API ans Backend proxien
# Modulstarts können durch Docker-Builds deutlich länger als 30 Sekunden dauern.
# Der Client muss auf die Lifecycle-Antwort warten können.
location /api/v1/modules/ {
proxy_pass http://platform_backend;
proxy_http_version 1.1;
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;
proxy_read_timeout 600s;
}
# Marketplace-Updates klonen Branches, bauen Images und starten Compose-Stacks.
# Diese Lifecycle-Antworten können länger als das normale API-Limit dauern.
location /api/v1/marketplace/modules/ {
proxy_pass http://platform_backend;
proxy_http_version 1.1;
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;
proxy_read_timeout 600s;
}
location /api/ {
proxy_pass http://platform_backend;
proxy_http_version 1.1;
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;
proxy_read_timeout 30s;
}
# Next.js benötigt Inline-Skripte für die React-Hydrierung. Die globale
# Plattform-CSP ohne 'unsafe-inline' würde trotz geladener JS-Dateien
# alle Client-Handler des Kalendertools blockieren.
location ~ "^/kalendartool(?<calendar_module_path>/.*)?$" {
proxy_pass http://platform_backend/api/v1/gateway/kalendartool$calendar_module_path;
proxy_http_version 1.1;
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;
proxy_read_timeout 60s;
proxy_hide_header Content-Security-Policy;
# add_header überschreibt hier die globale Header-Liste; die übrigen
# Sicherheits-Header deshalb erneut setzen.
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
}
# Modul-Routing (Phase 4): /slug/* wird intern an den
# Modul-Gateway des Backends übergeben (/api/v1/gateway/slug/*).
# Der Gateway prüft Session, Modul-Status und Berechtigung,
# bevor der Request an den Modul-Prozess proxied wird.
# WICHTIG: Plattform-Pfade (api, assets, login, …) sind ausgeschlossen,
# damit nur echte Modul-Slugs (3–100 Zeichen) weitergeleitet werden.
location ~ "^/(?!api/|assets/|login|profile|admin|403|404)(?<module_slug>[a-z0-9][a-z0-9-]{2,100})(?<module_path>/.*)?$" {
proxy_pass http://platform_backend/api/v1/gateway/$module_slug$module_path;
proxy_http_version 1.1;
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;
proxy_read_timeout 60s;
}
# SPA-Fallback für React Router
location / {
try_files $uri $uri/ /index.html;
}
}
}