# ============================================================================= # Gateway nginx configuration for Paca # ============================================================================= # # Single public entrypoint for the Paca stack: # /api/* → REST API service # /ws/* → Realtime service (Socket.IO) # /storage/* → MinIO object storage # /* → Web application (SPA) # # Mounted as /etc/nginx/conf.d/default.conf inside the nginx container. # -- Rate-limit zones --------------------------------------------------------- limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s; # -- WebSocket connection upgrade map ----------------------------------------- map $http_upgrade $connection_upgrade { default upgrade; '' close; } # Resolve Docker service names for variable-based proxy_pass targets. resolver 127.0.0.11 ipv6=off valid=30s; # -- Upstream pools ----------------------------------------------------------- upstream api_backend { server paca-api:8080; keepalive 32; } upstream realtime_backend { server paca-realtime:3001; keepalive 16; } # ============================================================================= server { listen 80; server_name _; server_tokens off; client_max_body_size 10m; # -- Compression ---------------------------------------------------------- gzip on; gzip_proxied any; gzip_comp_level 5; gzip_min_length 256; gzip_types application/javascript application/json application/wasm font/woff font/woff2 image/svg+xml text/css text/plain; # -- Security headers ----------------------------------------------------- add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; add_header X-XSS-Protection "0" always; # ========================================================================= # Routing # ========================================================================= # -- Object storage (MinIO) ----------------------------------------------- location /storage/ { set $minio_backend http://paca-minio:9000; rewrite ^/storage/(.*)$ /$1 break; proxy_pass $minio_backend; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host minio:9000; 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; client_max_body_size 0; proxy_request_buffering off; proxy_connect_timeout 10s; proxy_send_timeout 120s; proxy_read_timeout 120s; } # -- Realtime service (Socket.IO) ----------------------------------------- location /ws/ { proxy_pass http://realtime_backend/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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; proxy_connect_timeout 10s; proxy_send_timeout 60s; proxy_read_timeout 3600s; } # -- API routes ----------------------------------------------------------- location /api/ { limit_req zone=api burst=50 nodelay; limit_req_status 429; proxy_pass http://api_backend/api/; proxy_http_version 1.1; proxy_set_header Connection ""; 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_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # -- Local plugin frontend assets ----------------------------------------- location /plugins/ { alias /var/www/plugins/; autoindex off; types { application/javascript js; application/wasm wasm; text/css css; text/html html; image/svg+xml svg; font/woff woff; font/woff2 woff2; } add_header Cache-Control "public, max-age=900, immutable" always; } # -- MCP plugin bundles --------------------------------------------------- location /plugins-mcp/ { alias /var/www/plugins-mcp/; autoindex off; types { application/javascript js; } add_header Cache-Control "public, max-age=900, immutable" always; } # -- Web application (SPA) ------------------------------------------------ location / { set $web_backend http://paca-web:3000; proxy_pass $web_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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; proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; } }