使用环境变量配置Nginx proxy_pass出现Bad Gateway问题排查
1. 环境变量BACKEND_URL缺少协议头
当用变量作为proxy_pass的目标时,Nginx要求必须指定完整的协议(http://或https://)。如果你的BACKEND_URL只填了域名/IP+端口(比如backend:8080),Nginx无法识别协议类型,直接导致转发失败。
解决方法:
构建时传入的BACKEND_URL必须包含完整协议,比如http://backend:8080。
2. Resolver配置不匹配当前运行环境
你配置的resolver 169.254.169.253是AWS EC2实例的专属元数据DNS服务器,若容器运行在非AWS环境(本地Docker、阿里云、自建K8s集群等),这个DNS服务器无法解析后端域名,Nginx找不到目标服务器就会返回Bad Gateway。
解决方法:
替换为当前环境可用的DNS服务器:
- 本地Docker环境:用
8.8.8.8(Google公共DNS)或Docker内置DNS127.0.0.11 - K8s集群:使用集群DNS服务地址(如
kube-dns.kube-system.svc.cluster.local) - 其他环境:对应平台的公共DNS或内部DNS
修改示例:
resolver 8.8.8.8 valid=5s;
3. 路径转发规则不一致
使用变量proxy_pass $backend时,Nginx会把当前请求的完整路径(包括/test)追加到目标URL后;但如果硬编码时你在目标URL末尾加了斜杠(比如proxy_pass http://backend:8080/;),Nginx会自动去掉/test前缀,将请求转发到后端根路径。两种规则的转发路径不同,可能导致后端返回错误。
解决方法:
如果需要将/test映射到后端根路径,添加rewrite规则去掉前缀:
location /test { set $backend "${BACKEND_URL}"; rewrite ^/test/(.*)$ /$1 break; proxy_pass $backend; }
或者确保BACKEND_URL结尾带斜杠,调整配置:
location /test { set $backend "${BACKEND_URL}/"; # 保证变量值结尾有斜杠 proxy_pass $backend; }
4. 变量插值后的URL格式异常
检查容器内生成的nginx.conf,确认$backend的实际值没有多余引号或特殊字符。如果构建时传入的环境变量带引号,会导致proxy_pass的目标URL无效。
解决方法:
传入BACKEND_URL时不要带多余引号,比如:
docker build --build-arg BACKEND_URL=http://backend:8080 .
内容的提问来源于stack exchange,提问作者Ragnar

