Docker环境下Nginx反向代理其他容器的配置问题求助
问题:Docker环境下Nginx反向代理Jaeger容器的路径问题(无Docker Compose)
环境配置
Jaeger容器启动命令
docker run \ --name oqm_infra_jaeger \ -p 8090:16686 \ -p 8091:14268 \ -p 8096:4317 \ -e COLLECTOR_OTLP_ENABLED=true \ -d jaegertracing/all-in-one:1.42
Nginx容器启动命令
docker run \ --name nginx \ -p=80:80 \ --add-host host.docker.internal:host-gateway \ -v /etc/oqm/serviceConfig/infra/nginx/conf.d/:/etc/nginx/conf.d/\ -v /etc/oqm/serviceConfig/infra/nginx/conf.other.d/:/etc/nginx/conf.other.d/\ nginx
Nginx核心配置文件
/etc/nginx/conf.d/default.conf
upstream infra-jaeger { server host.docker.internal:8090; } server { listen 80; listen [::]:80; server_name localhost; access_log /var/log/nginx/host.access.log main; location /infra/jaeger/ { proxy_pass http://infra-jaeger/; #proxy_redirect http://infra-jaeger/ /; proxy_redirect off; add_header Pragma "no-cache"; add_header Cache-Control "no-cache"; proxy_set_header Host $http_host/infra/jaeger; sub_filter 'action="/' 'action="/infra/jaeger/'; sub_filter 'href="/' 'href="/infra/jaeger/'; sub_filter 'src="/' 'src="/infra/jaeger/'; sub_filter_once off; include /etc/nginx/conf.other.d/proxy_params; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
/etc/nginx/conf.other.d/proxy_params
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;
已尝试的配置及问题
尝试1:错误的路径映射
location /infra/jaeger/ { proxy_pass http://infra-jaeger/infra/jaeger/; 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_redirect https://infra-jaeger/ /; }
- 问题:页面返回200,但静态资源(如
image.svg)请求路径未带上/infra/jaeger/前缀,导致404加载失败。
尝试2:Host头格式错误
location /infra/jaeger/ { proxy_pass http://infra-jaeger/; proxy_redirect off; add_header Pragma "no-cache"; add_header Cache-Control "no-cache"; proxy_set_header Host $http_host/infra/jaeger; sub_filter 'action="/' 'action="/infra/jaeger/'; sub_filter 'href="/' 'href="/infra/jaeger/'; sub_filter 'src="/' 'src="/infra/jaeger/'; sub_filter_once off; include /etc/nginx/conf.other.d/proxy_params; }
- 问题:直接返回400错误,提示
400 Bad Request: malformed Host header,因为Host头不能包含路径部分。
尝试3:资源内容被错误替换
location /infra/jaeger/ { proxy_pass $scheme://infra-jaeger/; #proxy_redirect http://infra-jaeger/ /; # tell backend that message compression not allowed proxy_set_header Accept-Encoding ""; sub_filter_types *; sub_filter 'action="/' 'action="/infra/jaeger/'; sub_filter 'href="/' 'href="/infra/jaeger/'; sub_filter 'src="/' 'src="/infra/jaeger/'; sub_filter 'action="./' 'action="/infra/jaeger/'; sub_filter 'href="./' 'href="/infra/jaeger/'; sub_filter 'src="./' 'src="/infra/jaeger/'; sub_filter_once off; #add_header Pragma "no-cache"; #add_header Cache-Control "no-cache"; include /etc/nginx/mime.types; include /etc/nginx/conf.other.d/proxy_params; }
- 问题:初始页面可加载,路径看似已替换,但所有CSS/JS资源返回的是主HTML页面内容,而非实际资源。
解决思路
1. 修正Host头配置
Host头只能包含域名/IP和端口,不能带路径。将proxy_set_header Host $http_host/infra/jaeger;改为proxy_set_header Host $http_host;,即可避免400错误。
2. 优化Nginx路径匹配与代理规则
确保proxy_pass路径匹配正确,同时让Nginx精准处理响应内容替换:
location /infra/jaeger/ { proxy_pass http://infra-jaeger/; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Prefix /infra/jaeger; # 传递前缀给Jaeger服务 # 禁用后端压缩,确保sub_filter能正常解析响应内容 proxy_set_header Accept-Encoding ""; # 仅对HTML、JS、CSS类型的响应做路径替换 sub_filter_types text/html application/javascript text/css; sub_filter '="/' '="/infra/jaeger/'; sub_filter './' '/infra/jaeger/'; sub_filter_once off; include /etc/nginx/conf.other.d/proxy_params; }
- 说明:
X-Forwarded-Prefix可让Jaeger自身生成带前缀的URL,减少Nginx内容替换的工作量。
3. 让Jaeger直接使用前缀启动(最优方案)
修改Jaeger容器启动命令,添加环境变量指定基础路径,让Jaeger自身生成的所有URL都带上/infra/jaeger前缀,无需Nginx做内容替换:
docker run \ --name oqm_infra_jaeger \ -p 8090:16686 \ -p 8091:14268 \ -p 8096:4317 \ -e COLLECTOR_OTLP_ENABLED=true \ -e QUERY_BASE_PATH=/infra/jaeger \ -d jaegertracing/all-in-one:1.42
对应的简化Nginx配置:
location /infra/jaeger/ { proxy_pass http://infra-jaeger/infra/jaeger/; proxy_set_header Host $http_host; include /etc/nginx/conf.other.d/proxy_params; }
- 此方案最可靠,避免了Nginx替换内容时可能出现的资源损坏问题。
4. 修复资源返回HTML的问题
尝试3中资源返回HTML,是因为sub_filter_types *让Nginx对所有类型的响应(包括JS/CSS)做字符串替换,破坏了资源内容。只需指定需要替换的类型(text/html、application/javascript、text/css)即可,不要使用通配符*。
内容的提问来源于stack exchange,提问作者Snappawapa
相关产品推荐
相关产品推荐

