尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Nginx 容器化部署实战:SPA 路由、Cookie 透传与 WebSocket 全配置详解

Nginx 容器化部署实战:SPA 路由、Cookie 透传与 WebSocket 全配置详解 场景容器内同时跑 Nginx 和 Go 后端。Nginx 负责前端 Vue SPA 静态资源7777 端口、/api反向代理到 Go8888、/static静态资源代理上传的图片/文件并带 30 天强缓存。同时解决四个经典问题SPA 路由 404、Cookie 丢失、WebSocket 握手失败、非 root 用户运行权限。1. 完整配置nginx.conf# Nginx 配置文件 # 容器以非 root 用户 (1000) 运行不切换用户 worker_processes auto; # 自动匹配 CPU 核数 pid /run/nginx/nginx.pid; # PID 文件位置非 root 可写 error_log /var/log/nginx/error.log warn; events { worker_connections 1024; # 单 worker 最大连接数 } http { # 非 root 用户临时目录覆盖 Alpine 默认的 /var/lib/nginx/tmp否则 403 权限错误 client_body_temp_path /tmp/nginx_client_body; proxy_temp_path /tmp/nginx_proxy; fastcgi_temp_path /tmp/nginx_fastcgi; uwsgi_temp_path /tmp/nginx_uwsgi; scgi_temp_path /tmp/nginx_scgi; # MIME 类型 include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; server { listen 7777; # 前端入口端口 server_name _; client_max_body_size 30M; # 上传文件大小限制壁纸/图片/头像 # ───────────────────────────── # 前端静态文件 SPA 路由 # ───────────────────────────── location / { root /usr/share/nginx/html; index index.html; # SPA 路由核心所有未匹配的路径都返回 index.html # 由前端 vue-router 接管路由history 模式 try_files $uri $uri/ /index.html; } # ───────────────────────────── # 后端 API 反向代理 # ───────────────────────────── location /api/ { proxy_pass http://127.0.0.1:8888; # 注意无尾斜杠 保留原始 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; # 确保 cookie 透传解决 session/JWT 丢失问题 proxy_set_header Cookie $http_cookie; proxy_pass_header Set-Cookie; # 禁止 nginx 修改重定向解决 307 二次请求问题 proxy_redirect off; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; # 代理超时聊天/SSE 流式接口需要 proxy_connect_timeout 90; proxy_read_timeout 90; } # ───────────────────────────── # 静态文件代理壁纸、聊天文件、头像等 # ───────────────────────────── location /static/ { proxy_pass http://127.0.0.1:8888; # Go 后端 r.Static(/static, ./static) 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; # 静态资源强缓存 30 天 expires 30d; add_header Cache-Control public, immutable; } } }2. 逐段讲解每个配置解决什么问题2.1 SPA 路由 ——try_fileslocation / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; }问题Vue Router 用 history 模式时URL 是/blog/article/123而不是/#/blog/article/123。用户刷新页面时Nginx 找不到对应的真实文件返回 404。解决try_files依次尝试$uri— 命中真实文件如/assets/index-xxx.js$uri/— 命中目录自动找 index.html/index.html— 兜底交给前端路由处理注意后端要有对应的 API 接口或返回 404 页面避免 SEO 无效页面被索引。2.2 Cookie 透传 —— 解决登录态丢失proxy_set_header Cookie $http_cookie; proxy_pass_header Set-Cookie;问题默认 Nginx 会透传 Cookie但某些场景跨域、代理到不同端口会导致 Session 丢失。显式声明后Cookie把客户端 Cookie 原样传给后端Set-Cookie后端设置的 Cookie 原样返回给客户端2.3 307 重定向问题 ——proxy_redirect off问题Go 后端某些接口返回 307如 HTTP→HTTPS 跳转Nginx 默认会改写 Location 头导致客户端跳转到错误地址出现二次请求或死循环。解决proxy_redirect off;让 Location 头原样透传。2.4 WebSocket —— 协议升级proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade;问题WebSocket 握手时客户端发Upgrade: websocket头HTTP/1.0 不支持长连接Nginx 必须用 HTTP/1.1 转发并带上 Upgrade/Connection 头否则握手失败。2.5 非 root 用户运行 —— 临时目录client_body_temp_path /tmp/nginx_client_body; proxy_temp_path /tmp/nginx_proxy;问题容器以USER 1000:1000运行时Nginx 默认的/var/lib/nginx/tmp没有写权限上传文件或代理大响应时直接 403/500。解决把临时目录全部指到/tmp下并在 Dockerfile 里chown给用户 1000。2.6 上传大小限制client_max_body_size 30M;不设置默认只有 1M上传壁纸/图片会报413 Request Entity Too Large。3. 验证与排查命令# 检查配置语法nginx-t-c/etc/nginx/nginx.conf# 容器内实时日志dockerlogs-fledger-service# 手动验证各路由curl-Ihttp://localhost:7777/# 前端页面curl-Ihttp://localhost:7777/api/v1/user/info# API 代理curl-Ihttp://localhost:7777/static/wallpapers/xxx.jpg# 静态资源看 Cache-Control4. 常见问题排查表现象原因解决刷新页面 404没配try_files加try_files $uri $uri/ /index.html;登录后刷新掉登录态Cookie 没透传加proxy_set_header Cookieproxy_pass_header Set-CookieWebSocket 连不上缺 Upgrade 头加proxy_http_version 1.1 Upgrade/Connection 头上传 413体积超限client_max_body_size 30M;上传 403非 root 无写权限临时目录指到/tmp chown图片不更新强缓存 30 天文件名带 hash 或改用no-cache接口 502后端没启动/端口不对检查proxy_pass地址与后端监听端口5. 与 Dockerfile 的配合# 非 root 运行所需创建目录并授权 RUN mkdir -p /var/log/nginx /run/nginx /var/lib/nginx/logs /tmp/nginx_client_body /tmp/nginx_proxy \ chown -R 1000:1000 /app /usr/share/nginx/html /var/log/nginx /run/nginx /var/lib/nginx /tmp/nginx_client_body /tmp/nginx_proxy USER 1000:1000总结这份配置的核心价值一个 7777 端口搞定前后端静态资源 API WebSocket 静态文件外部只暴露一个入口四个经典坑全部规避SPA 404、Cookie 丢失、WS 握手失败、非 root 权限性能静态资源 30 天强缓存后端只处理动态请求
返回列表