upstream backend { server backend:8080; } upstream frontend { server frontend:3000; } server { listen 80; server_name localhost; # 安全头 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; location /sitemap.xml { proxy_pass http://backend/api$request_uri; 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; } location ~ ^/sitemap-([0-9]+)\.xml$ { proxy_pass http://backend/api$request_uri; 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 路由 - 所有 /api/ 开头的请求转发到后端 location /api/ { proxy_pass http://backend; 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 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 缓冲设置 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; # 错误处理 proxy_intercept_errors on; error_page 502 503 504 /50x.html; } location ^~ /uploads/ { proxy_pass http://backend/uploads/; 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; expires 1y; add_header Cache-Control "public, immutable"; add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Content-Type, Accept"; } # 静态文件路由 - 直接转发到前端 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { proxy_pass http://frontend; 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; # 缓存设置 expires 1y; add_header Cache-Control "public, immutable"; } # 微信公众号验证文件路由 - 根目录的TXT文件直接访问后端uploads目录 location ~ ^/[^/]+\.txt$ { # 检查文件是否存在于uploads目录 set $uploads_path /uploads$uri; if (-f $uploads_path) { proxy_pass http://backend; # 缓存设置 expires 1h; add_header Cache-Control "public"; # 允许跨域访问 add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Content-Type, Accept"; break; } # 如果文件不存在,返回404 return 404; } # 健康检查 location /health { proxy_pass http://backend/health; 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; } # 默认路由 - 所有其他请求转发到前端 location / { proxy_pass http://frontend; 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; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 缓冲设置 proxy_buffering off; # 错误处理 proxy_intercept_errors on; error_page 502 503 504 /50x.html; } # 错误页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }