# 生产 Nginx:SPA + API/WebSocket 反代 + 对象存储公共读路径 # 上游服务名与 docker-compose.prod.yml 中 service 名一致 map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream kefu_api { server api:8080; keepalive 32; } upstream kefu_minio { server minio:9000; } server { listen 80; server_name _; client_max_body_size 20m; # 上传/长连接 proxy_read_timeout 3600s; proxy_send_timeout 3600s; # 健康探针(不经 API) location = /healthz { access_log off; add_header Content-Type text/plain; return 200 'ok'; } # 后端健康检查 location = /health { proxy_pass http://kefu_api/health; proxy_http_version 1.1; 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 + WebSocket(/api/ws、/api/widget/ws) location /api/ { proxy_pass http://kefu_api/api/; proxy_http_version 1.1; 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 Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_buffering off; } # 图片公共访问:浏览器访问 /files/* → MinIO bucket kefu/* # 须与 STORAGE_PUBLIC_BASE_URL=https://你的域名/files 一致 location /files/ { proxy_pass http://kefu_minio/kefu/; proxy_http_version 1.1; 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; # 允许跨域拉取图片(嵌入站点) add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always; if ($request_method = OPTIONS) { return 204; } expires 7d; add_header Cache-Control "public" always; } # 前端静态资源 location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } # 构建产物长缓存 location /assets/ { root /usr/share/nginx/html; expires 30d; add_header Cache-Control "public, immutable"; try_files $uri =404; } }