upstream swoole { server swoole-upstream:9501; keepalive 32; } server { listen 80; server_name localhost; root /var/app/public; index index.html index.htm; charset utf-8; # === Connection Optimization === keepalive_timeout 65; keepalive_requests 1000; sendfile on; tcp_nopush on; tcp_nodelay on; # === Buffers and Limits === client_max_body_size 64M; large_client_header_buffers 4 32k; # === File Descriptor Cache === open_file_cache max=2000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # === Gzip Compression === gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_min_length 256; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/x-javascript application/xml application/rss+xml application/atom+xml image/svg+xml font/woff2 application/font-woff2 application/vnd.ms-fontobject application/x-font-ttf; # === Security Headers === add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; # === Specific Caching for Build Assets (Vite hashed) === # These files have content hashes in names — cache forever location ^~ /build/assets/ { access_log off; expires max; add_header Cache-Control "public, no-transform, immutable"; try_files $uri =404; } # === Static Assets from /dist/ and /plugins/ (legacy libs) === location ^~ /dist/ { access_log off; expires 30d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } location ^~ /plugins/ { access_log off; expires 30d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } location ^~ /assets/ { access_log off; expires 30d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } # === Font files — long cache + CORS === location ~* \.(woff|woff2|ttf|eot|otf)$ { access_log off; expires max; add_header Cache-Control "public, no-transform, immutable"; add_header Access-Control-Allow-Origin "*"; try_files $uri =404; } # === Image files === location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { access_log off; expires 30d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } # === Direct Access to Static Files (CSS/JS catch-all) === location ~* \.(css|js)$ { access_log off; expires 7d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } # === Hashed Files Caching (DB-served files) === location /RequestData/File/ { 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_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_pass http://swoole; # Browser caching for hashed assets add_header Cache-Control "public, max-age=31536000, immutable"; } # === SSE Streaming (No buffering, long timeouts) === location /sse/ { 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_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_pass http://swoole; # Disable buffering and caching for real-time streaming proxy_buffering off; proxy_cache off; chunked_transfer_encoding off; # Extended timeouts for long-lived streams proxy_read_timeout 86400s; proxy_send_timeout 86400s; } # === Application proxy (catch-all) === location / { # Try static file first, then proxy to Swoole try_files $uri @swoole; } location @swoole { 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_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_pass http://swoole; # Proxy buffering for better throughput for normal requests proxy_buffering on; proxy_buffer_size 32k; proxy_buffers 8 64k; } # === Manifest and PWA === location = /manifest.json { access_log off; expires 1d; add_header Cache-Control "public, no-transform"; try_files $uri =404; } location = /sw.js { access_log off; expires -1; add_header Cache-Control "no-cache, no-store, must-revalidate"; try_files $uri =404; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } access_log off; error_log /var/log/nginx/error.log error; }