Files
mpm/docker/nginx/nginx.conf
2026-10-10 15:51:30 +02:00

165 lines
6.1 KiB
Nginx Configuration File
Raw 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)
# Moduloberflächen liegen auf einem eigenen Host; der Hostname wird beim Start
# aus MODULE_PUBLIC_ORIGIN in diese Konfiguration eingesetzt.
# =============================================================
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 default_server;
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 $http_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 $http_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 $http_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;
}
# Alte Modul-Links auf dem Plattformhost führen über das Einmal-Ticket
# zum getrennten Modulhost. Hier wird kein Modul-JavaScript ausgeliefert.
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/auth/module-open/$module_slug;
proxy_http_version 1.1;
proxy_set_header Host $http_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;
}
# SPA-Fallback für React Router
location / {
try_files $uri $uri/ /index.html;
}
}
# Dieser Host liefert ausschließlich Modulpfade und den Ticket-Übergang.
# Management-API, Login, Admin-Frontend und Plattform-Cookies sind hier
# nicht erreichbar. Der Name wird beim Containerstart validiert eingesetzt.
server {
listen 8080;
server_name __MODULE_HOSTNAME__;
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'; worker-src 'none'; 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;
# Auf lokalen Macs kann dieser Host zuvor für MPM verwendet worden sein.
# Bekannte Plattform-Einstiege führen zum konfigurierten Plattformhost.
location = / { return 302 __PLATFORM_ORIGIN__/; }
location ~ "^/(login|admin|profile|assets|403|404)(/|$)" {
return 302 __PLATFORM_ORIGIN__$request_uri;
}
location = /__mpm_module_handoff {
access_log off;
proxy_pass http://platform_backend/api/v1/auth/module-handoff$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_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;
}
location ^~ /api/ { return 404; }
location ~ "^/(?<module_slug>[a-z0-9][a-z0-9-]{2,100})(?<module_path>/.*)?$" {
proxy_pass http://platform_backend/api/v1/gateway/$module_slug$module_path$is_args$args;
proxy_http_version 1.1;
proxy_set_header Host $http_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;
proxy_hide_header Service-Worker-Allowed;
}
location / { return 404; }
}
}