server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss; client_max_body_size 800m; # SPA routing - all routes to index.html # 注意:不能加 $uri/,否则 /assets 等与构建产物目录同名的路由会被当成目录访问,返回 403 location / { try_files $uri /index.html; } # API proxy # Production environment: proxy to production API container on isolated network # Use static container name to avoid URI stripping issues with variable-based proxy_pass resolver 127.0.0.11 valid=10s; resolver_timeout 5s; location /api/ { proxy_pass http://xiaoxia-api-production:8000/api/; 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_read_timeout 300s; proxy_send_timeout 300s; proxy_request_buffering off; } # Generated files proxy location /generated-files/ { alias /app/generated/; } # Assets with legacy fallback (higher priority than generic static regex) # 部署期间,缓存了旧版 index.html 的用户会请求旧版带 hash 的 assets 文件 # 先在当前镜像中找,找不到去 legacy-assets 目录找(从旧版本容器中备份的) location ^~ /assets/ { expires 1y; add_header Cache-Control "public, immutable"; try_files $uri /assets-legacy$uri =404; } # Cache static assets location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } }