server { listen 80; server_name localhost fibdash.local fibdash.growheads.de; # Enable gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # Security headers add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-cross-origin"; # Relaxed CSP for development with Google Sign-In add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://apis.google.com https://www.google.com https://ssl.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://accounts.google.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: https://accounts.google.com https://ssl.gstatic.com; connect-src 'self' https://accounts.google.com https://www.googleapis.com; frame-src https://accounts.google.com;"; # Proxy settings for WebSocket connections (for hot reload) 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; # API routes - proxy to Express backend location /api/ { proxy_pass http://localhost:5000; proxy_redirect off; # CORS headers for development add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept"; # Handle preflight requests if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept"; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } } # WebSocket proxy for webpack-dev-server hot reload location /ws { proxy_pass http://localhost:5001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } # Webpack HMR specific endpoint location /__webpack_hmr { proxy_pass http://localhost:5001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } # Static assets and main application - proxy to webpack-dev-server location / { proxy_pass http://localhost:5001; proxy_redirect off; # Enable hot module replacement 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; # Handle WebSocket upgrade for HMR proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # Disable caching for development add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; } # Health check endpoint location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } # Error pages error_page 404 /404.html; error_page 500 502 503 504 /50x.html; # Logging access_log /var/log/nginx/fibdash_access.log; error_log /var/log/nginx/fibdash_error.log warn; } # WebSocket upgrade map map $http_upgrade $connection_upgrade { default upgrade; '' close; }