Nginx 反向代理配置实战:最常见的10个坑与可复制模板(附排错清单)
Nginx 反向代理配置实战:最常见的 10 个坑与可复制模板(附排错清单)
很多新手第一次配反向代理时,都会遇到同一类症状:
- 页面 502/504
- 静态资源 404
- 登录后不断跳回登录页(cookie 丢了)
- WebSocket 连接不上
- 访问慢、偶发超时
这篇文章不讲“概念课”,直接给你一套能落地的 Nginx 反向代理模板,并把最常见的坑按“现象 → 原因 → 修复”列清楚。你照着做,基本能把 80% 的代理问题一次性解决。
适用场景:VPS/云服务器、Docker、宝塔/1Panel、自建 API、前后端分离、站群反代等。
一、反向代理到底代理了什么?(一句话版本)
反向代理 = 用户访问 Nginx,Nginx 再把请求转发给后端服务(upstream)并把响应返回。
你要保证三件事:
- Nginx 能连上后端(网络/端口/健康)
- Nginx 转发时“请求头/路径/协议”没被你改坏
- Nginx 把响应(包含重定向、cookie、压缩、缓存)正确地交回给浏览器
二、推荐的基础模板(HTTP 反代)
先给一个通用模板,你改域名、端口就能跑:
server {
listen 80;
server_name example.com;
# 可选:上传大文件时避免 413
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:3000;
# 让后端拿到真实信息(非常重要)
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_http_version 1.1;
proxy_set_header Connection "";
# 超时(按业务调)
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
如果你是 Docker 容器,127.0.0.1 不一定能访问到容器,后面“坑 1”会讲。
三、最常见 10 个坑(现象 → 原因 → 修复)
坑 1:Nginx 配了 127.0.0.1:xxxx,结果一直 502
现象:浏览器 502,error.log 里常见 connect() failed (111: Connection refused)。
原因:
- 后端服务根本没启动
- 后端只监听了
127.0.0.1但你在容器里访问 - Docker 容器与宿主网络隔离,你的 Nginx 在宿主上,后端在容器里(或反过来)
修复:
- 在服务器上先验证连通:
curl -I http://127.0.0.1:3000 ss -lntp | grep 3000 - Docker 场景:
- 如果 Nginx 和后端在同一个 docker network,用服务名:
proxy_pass http://app:3000; - 如果 Nginx 在宿主,后端在容器,记得做端口映射:
-p 3000:3000
- 如果 Nginx 和后端在同一个 docker network,用服务名:
坑 2:proxy_pass 末尾的 / 写错导致路径乱了
现象:后端接口 404、静态资源路径错、API 被拼错。
原因:Nginx 对 location 与 proxy_pass 的“斜杠规则”非常反直觉。
location /api/ { proxy_pass http://127.0.0.1:8080/; }/api/xxx会转发成/xxx
location /api/ { proxy_pass http://127.0.0.1:8080; }/api/xxx会转发成/api/xxx
修复建议(记住一个):
- 如果你希望“去掉 /api 前缀”,就让
proxy_pass也以/结尾。 - 如果你希望“保留 /api 前缀”,就不要在
proxy_pass末尾加/。
坑 3:后端生成的跳转是 http/https 错乱,出现循环重定向
现象:浏览器一直跳转,或者登录后又回登录页。
原因:后端不知道用户实际是通过 HTTPS 访问的(尤其是你前面还有 CDN/SLB)。
修复:
- 反代时加上:
proxy_set_header X-Forwarded-Proto $scheme; - 后端框架里启用“信任代理头”(不同语言不同配置)。
坑 4:WebSocket 连接不上(常见于 Next.js、Socket.IO、面板类应用)
现象:页面能打开,但 WS 报错 400/426/502。
修复模板:
location /socket.io/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
坑 5:静态资源缓存把你“坑惨”,更新后用户一直看到旧版本
现象:你明明更新了前端,但用户还是旧页面。
原因:CDN / 浏览器 / Nginx 缓存策略太激进。
修复思路:
- 静态资源走 hash 文件名(最稳)
- 对 HTML 主入口不要长缓存:
location = /index.html { add_header Cache-Control "no-cache"; }
坑 6:上传文件 413 Request Entity Too Large
修复:
client_max_body_size 50m;
如果后端也有限制(如 PHP、Node、网关),也要同步调。
坑 7:反代后真实 IP 变成 127.0.0.1
原因:你没把 IP 相关头转发给后端。
修复:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
如果前面还有 CDN/SLB,要让 Nginx 先拿到真实 IP(real_ip 模块配置),否则传下去的也不准。
坑 8:反代到 HTTPS 后端时证书校验失败
现象:error.log 里 SSL certificate verify failed。
修复(两种):
- 正确做法:给后端配可信证书(或用内网证书体系)。
- 临时绕过(不推荐长期):
proxy_ssl_verify off;
坑 9:504 Gateway Time-out(后端慢/长任务)
修复:
- 增大读取超时:
proxy_read_timeout 300s; - 更好的做法:把长任务做成异步(队列/回调),避免请求一直挂着。
坑 10:同时反代多个后端,负载均衡/健康检查没配好
推荐 upstream 模板:
upstream api_backend {
server 10.0.0.11:8080 max_fails=3 fail_timeout=10s;
server 10.0.0.12:8080 max_fails=3 fail_timeout=10s;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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;
}
}
四、上线前 7 条排错清单(照着查就行)
nginx -t是否通过curl -I http://后端地址:端口是否 200- 查看
error.log里最靠前的报错关键词:connect() failed/upstream timed out - 是否正确设置了
Host与X-Forwarded-Proto - 路径是否被
/规则搞乱(重点看/api) - WebSocket 是否加了 Upgrade/Connection
- CDN/HTTPS 终止点在哪里?真实协议/真实 IP 是否正确透传
五、结语:建议把“反代模板”当成基础设施复用
Nginx 反向代理不是背概念,而是把一套稳的模板沉淀下来。
你可以把本文的模板拆成三个片段收藏:
- 基础 HTTP 反代模板
/api前缀处理模板- WebSocket 模板
下次换项目,直接套用再微调,比从零猜配置靠谱得多。
