NGINX配置子目录反向代理访问返回502/404错误问题咨询
Ubuntu 20.04 Nginx子路径反向代理配置方案
前置排查
配置代理规则前先在Nginx所在主机执行连通性校验:
- 针对每个后端服务执行curl测试,例如测试ESPHome服务执行
curl http://10.0.0.185:6502 - 如果curl返回连接拒绝、超时,先排查后端服务是否正常启动、防火墙是否开放对应端口、服务是否监听在正确的地址上,后端端口不通时Nginx必然返回502 Bad Gateway错误
故障根因
你遇到的502、403、请求挂起、404问题,核心原因有三点:
- 子路径转发时未剥离路径前缀,后端服务收到的请求自带
/esphome//adguard这类前缀,而ESPHome、AdGuard Home、Frigate这类自托管服务默认仅处理根路径下的请求,找不到对应资源就返回404,权限校验不通过则返回403 - 基础代理头缺失、超时配置过短,会导致后端无法识别请求来源、长连接被Nginx提前断开,对应出现502、请求无响应挂起的问题
- 仅靠给
proxy_pass加末尾斜杠的方式,只能解决简单场景的路径拼接问题,遇到后端返回3xx重定向、静态资源用绝对路径加载的情况会直接失效
正确配置示例
替换原有配置文件内容如下:
server { listen 80 default_server; server_name 10.0.0.185; # 根路径代理,保留原有可用配置 location / { proxy_pass http://10.0.0.185:6052; 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; } # ESPHome子路径代理 location ^~ /esphome/ { rewrite ^/esphome/(.*)$ /$1 break; proxy_pass http://10.0.0.185:6502; 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_redirect ~^/(.*)$ /esphome/$1; # 适配长连接场景,避免请求超时挂起 proxy_read_timeout 300s; proxy_send_timeout 300s; } # AdGuard Home子路径代理 location ^~ /adguard/ { rewrite ^/adguard/(.*)$ /$1 break; proxy_pass http://10.0.0.185:8080; 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_redirect ~^/(.*)$ /adguard/$1; } # Frigate子路径代理 location ^~ /frigate/ { rewrite ^/frigate/(.*)$ /$1 break; proxy_pass http://10.0.0.185:5000; 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_redirect ~^/(.*)$ /frigate/$1; proxy_read_timeout 300s; proxy_send_timeout 300s; } }
关键配置说明
- 子路径匹配统一用
^~ /xxx/格式,末尾必须带斜杠,优先级高于普通前缀匹配,避免误匹配其他路径 rewrite规则负责剥离请求中的子路径前缀,例如访问/esphome/api/test时,转发给后端的实际路径为/api/test,和后端预期的根路径请求规则一致- 必须添加
proxy_set_header Host $host配置,之前的配置缺失该头,会导致后端无法识别正确的访问地址,触发域名校验失败、权限拦截返回403 proxy_redirect规则负责修正后端返回的3xx重定向地址,自动补上子路径前缀,避免跳转时跳出子目录- 针对Frigate这类存在视频流、长连接的服务,将代理超时时间调整为300秒以上,解决连接提前断开导致的请求挂起问题
生效操作与注意事项
- 配置修改完成后,先执行
nginx -t校验配置语法,确认无报错后执行systemctl reload nginx重载配置,不要直接restart服务避免业务中断 - 如果配置后出现JS、CSS、图片等静态资源加载失败的问题,需要在对应后端服务的配置中指定基础路径(Base URL/Base Path)为当前设置的子路径,例如ESPHome在
web_server配置段添加base_url: /esphome,让后端生成的资源链接自动携带子路径前缀 - 测试时优先使用浏览器无痕模式,避免本地缓存的错误响应导致假故障
内容的提问来源于stack exchange,提问作者curt
相关产品推荐
相关产品推荐

