必须配置proxy_set_header传递真实请求头,否则tomcat无法获取host、客户端ip、协议等信息,导致登录失败、重定向错误和静态资源404;proxy_pass末尾斜杠影响uri重写;https场景下还需在tomcat connector中设置secure="true"、scheme="https"、proxyport="443"。

能直接转发,但必须加 proxy_set_header,否则 Tomcat 拿不到真实请求头,登录、重定向、静态资源路径全会出问题。
location / 里只写 proxy_pass 是不够的
很多人照着教程改完 proxy_pass http://127.0.0.1:8080 就以为完事了,结果访问首页能打开,点登录跳转 404,或者 CSS 加载失败。根本原因是 Tomcat 收到的请求里 Host 还是 127.0.0.1:8080,不是用户实际访问的域名;X-Forwarded-For 为空,后端日志全是 127.0.0.1。
必须显式补全这几个关键 header:
-
proxy_set_header Host $host;—— 把原始 Host 传给 Tomcat,否则 Spring Boot 的重定向 URL 会错 -
proxy_set_header X-Real-IP $remote_addr;—— 让 Tomcat 能拿到真实客户端 IP -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 兼容多层代理场景 -
proxy_set_header X-Forwarded-Proto $scheme;—— HTTPS 下必须加,否则 Spring Security 可能拒绝跳转
proxy_pass 末尾斜杠影响 URI 重写
这个细节几乎没人提,但一踩一个准:proxy_pass 后面的 URL 末尾有没有 /,决定了 Nginx 是否截掉匹配的 location 前缀。
比如配置了 location /api/ { proxy_pass http://127.0.0.1:8080/; },那么 /api/user 会被转发为 http://127.0.0.1:8080/user(/api/ 被删了);但如果写成 proxy_pass http://127.0.0.1:8080;(没斜杠),就会转发为 http://127.0.0.1:8080/api/user(原样带过去),而 Tomcat 根本不认 /api/user 这个路径。
常见做法:
- Tomcat 应用部署在 ROOT 下(即访问
http://localhost:8080/就是应用首页)→proxy_pass末尾加/ - Tomcat 应用部署在子路径如
/myapp→proxy_pass末尾不加/,并确保 location 匹配前缀和应用路径一致
HTTP 和 HTTPS 场景下 Tomcat 配置要区分
Nginx 做 HTTPS 终止是最常见也最推荐的方式,这时 Tomcat 只跑 HTTP,但必须告诉它“外面其实是 HTTPS”,否则重定向会生成 http:// 链接。
在 Tomcat 的 server.xml 里,对应 HTTP Connector 需要加三个属性:
protocol="HTTP/1.1"-
secure="true"—— 表示该连接逻辑上是安全的 -
scheme="https"—— 强制让 Tomcat 生成https://开头的 URL -
proxyPort="443"—— 告诉 Tomcat 外面的 HTTPS 端口是 443
完整示例:<connector port="8080" protocol="HTTP/1.1" secure="true" scheme="https" proxyport="443"></connector>
转发失败时先看 502 Bad Gateway 日志在哪边
502 不等于 Nginx 配错了,大概率是 Tomcat 根本没响应。排查顺序很关键:
- 用
curl -v http://127.0.0.1:8080直连 Tomcat,确认它自己能正常返回(注意看 HTTP 状态码,不是只看页面是否显示) - 检查 Tomcat 的
server.xml中Connector的address属性:如果写了127.0.0.1,Nginx 在另一台机器上就连接不上;应改为0.0.0.0或留空 - 查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,里面会有类似connect() failed (111: Connection refused) while connecting to upstream的提示,说明网络或端口不通 - 防火墙常被忽略:
systemctl status firewalld或ufw status,确保 8080 端口对 Nginx 所在机器开放
真正难调的不是语法,而是 Nginx 和 Tomcat 之间那几行 header 和 connector 属性的配合——少一个,就可能让登录态失效、重定向跳错、前端资源 404。











