# FastCGI-Cache-Einstellungen fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=PHPCACHE:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; # Hardcoded Umgebungsmodus basierend auf Template-Ersetzung map $http_host $env_mode { default "${APP_ENV}"; } # Dynamische Cache-Kontrolle basierend auf Umgebungsvariable map $env_mode $should_skip_cache { default 0; # Standard (Produktion): Cache aktivieren development 1; # Entwicklung: Cache deaktivieren testing 1; # Testing: Cache deaktivieren } # Skip-Cache für Sessions und basierend auf Umgebung map $http_cookie$should_skip_cache $skip_cache { "~ms_context" 1; # Sessions nie cachen "~1$" 1; # Cache überspringen, wenn should_skip_cache = 1 default 0; # Ansonsten cachen } map $host $block_health { default 1; # Blockiere alles localhost 0; # Erlaube nur Host "localhost" } upstream php-upstream { server php:9000; # „php“ ist durch Network-Alias immer erreichbar } server { listen 80; server_name localhost; return 301 https://$host$request_uri; } server { # Korrigierte HTTP/2 Syntax listen 443 ssl; listen [::]:443 ssl; listen 443 quic; # QUIC für HTTP/3 // Removed "reuseport" listen [::]:443 quic; http2 on; # Neue Syntax für HTTP/2 http3 on; add_header Alt-Svc 'h3=":443"; ma=86400; persist=1, h2=":443"; ma=86400'; server_name localhost; #ssl_certificate /etc/nginx/ssl/localhost+2.pem; #ssl_certificate_key /etc/nginx/ssl/localhost+2-key.pem; #ssl_certificate /etc/nginx/ssl/fullchain.pem; #ssl_certificate_key /etc/nginx/ssl/privkey.pem; ssl_certificate /var/www/ssl/fullchain.pem; ssl_certificate_key /var/www/ssl/privkey.pem; # add_header Alt-Svc 'h3=":443"'; # Für HTTP/3 Unterstützung #add_header QUIC-Status $quic; ssl_protocols TLSv1.3 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; # Verbesserte SSL-Konfiguration #ssl_session_timeout 1d; #ssl_session_cache shared:SSL:10m; #ssl_session_tickets off; # OCSP Stapling (auskommentiert, wenn Zertifikate fehlen) # ssl_stapling on; # ssl_stapling_verify on; resolver 1.1.1.1 1.0.0.1 valid=300s; resolver_timeout 5s; root /var/www/html/public; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; autoindex off; } # Debug-Header für die Entwicklung add_header X-Environment $env_mode always; # Sicherheits-Header add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Permissions-Policy "geolocation=(), microphone=()" always; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; # CSP Header add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'" always; # Buffer-Größen anpassen client_body_buffer_size 10K; client_header_buffer_size 1k; client_max_body_size 10m; large_client_header_buffers 2 1k; brotli on; brotli_comp_level 6; brotli_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-componentFs text/x-cross-domain-policy; # Verbesserte Gzip-Kompression gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-componentFs text/x-cross-domain-policy; # Logs #access_log /var/log/nginx/access.log combined; #error_log /var/log/nginx/error.log error; access_log /dev/stdout; error_log /dev/stderr warn; # läuft aktuell oben über dynamischen include! #location / { # try_files $uri $uri/ /index.php?$query_string; # autoindex off; #} # Service-Worker explizit erlauben (auch im Production-Server ungefährlich!) location = /sw.js { # je nach Build-Ordner anpassen! alias /var/www/html/public/sw.js; add_header Cache-Control "no-cache, must-revalidate"; } # Caching Header für statische Dateien ohne Rate-Limiting location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable, max-age=31536000"; # Keine Rate-Limits für statische Dateien } # Assets ohne Rate-Limiting für ES6 Module Performance location ~* \.(css|js|map)$ { expires 1w; add_header Cache-Control "public, max-age=604800"; # Keine Rate-Limits für statische Assets } # location ~* \.(json|xml)$ { # expires 1d; # add_header Cache-Control "public, max-age=86400"; # } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass php-upstream; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_split_path_info ^(.+\.php)(/.+)$; # Wichtig: APP_ENV an PHP weitergeben fastcgi_param APP_ENV $env_mode; # HTTP Headers für SPA-Support weitergeben fastcgi_param HTTP_X_REQUESTED_WITH $http_x_requested_with; fastcgi_param HTTP_X_SPA_REQUEST $http_x_spa_request; fastcgi_param HTTP_CONTENT_TYPE $content_type; fastcgi_param HTTP_ACCEPT $http_accept; # Timeout-Einstellungen fastcgi_read_timeout 60s; fastcgi_connect_timeout 60s; fastcgi_send_timeout 60s; # Caching-Einstellungen fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; # Cache FastCGI-Antworten fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache PHPCACHE; fastcgi_cache_valid 200 60m; # Debug-Header hinzufügen add_header X-Cache-Status $upstream_cache_status; add_header X-Cache-Environment $env_mode; add_header X-Cache-Skip $skip_cache; # Für bessere Performance fastcgi_keep_conn on; fastcgi_hide_header X-Powered-By; } # Sicherheitseinstellungen location ~ /\.(?!well-known).* { deny all; } server_tokens off; # Massiv erhöhter Burst für ES6 Module mit 18+ parallelen Requests limit_req zone=mylimit burst=100 nodelay; location ~* /(?:uploads|files)/.*\.php$ { deny all; } # Healthcheck-Endpunkt location = /ping { access_log off; add_header Content-Type text/plain; return 200 'pong'; } error_page 404 /errors/404.html; error_page 403 /errors/403.html; error_page 500 502 503 504 /errors/50x.html; location /errors/ { internal; # Verhindert direkten Zugriff } }