Docker环境下Nginx反向代理上游Rails服务内容串位问题排查求助
Docker环境下Nginx反向代理上游Rails服务内容串位问题排查求助
大家好,我遇到了一个非常棘手的生产环境问题,折腾了好几天都没找到根源,想请各位大佬帮忙分析下排查方向:
环境背景
- 单台服务器用Docker托管多个Rails站点,所有站点通过唯一域名访问(所有域名解析到同一IP)
- Rails和Nginx都运行在独立Docker容器中
- Nginx版本1.23.1,基于官方镜像构建,仅额外安装了Certbot用于TLS证书管理
核心症状
刚启动Nginx时一切正常,每个域名请求都能返回对应站点的内容,但运行几个小时后会出现上游Rails代理内容串位的诡异情况,而静态资源的路由始终是正常的:
- 例如请求
https://www.meaaa.com,会返回bbb.me.com的HTML内容;由于页面里引用的静态资源是bbb.me.com的路径,而Nginx会根据请求域名从www.meaaa.com的静态目录找资源,导致所有静态资源返回404 - 请求
https://bbb.me.com时,反而会返回www.meaaa.com的HTML内容,同样出现静态资源找不到的问题
用curl验证的结果:
$ curl -s https://www.meaaa.com | grep '<title>' <title>BBB Site</title> $ curl -s https://bbb.me.com | grep '<title>' <title>MEAAA Site</title>
但直接在Nginx容器内部curl上游Rails服务,返回的内容是完全正确的:
$ curl -s http://aaa:3000 | grep '<title>' <title>MEAAA Site</title> $ curl -s http://bbb:3000 | grep '<title>' <title>BBB Site</title>
后续更新
原本只有两个HTTPS站点出现串位,后来我给更多站点开启HTTPS后,问题变得更复杂:
- 三个站点出现循环串位:请求aaa站点返回bbb内容,请求bbb返回ccc内容,请求ccc返回aaa内容
- 另外两个站点直接无响应
目前只能临时设置每60分钟重启一次Nginx来维持服务,同时正在搭建与生产环境完全一致的staging环境,希望能复现问题以便排查。
相关Nginx配置
www.meaaa.com站点配置
upstream aaa-rails { server aaa:3000; } server { server_name www.meaaa.com source.meaaa.com aaa.meinternal.com; root /var/www/aaa-rails/public; index index.html index.htm; location /cms { deny 172.22.188.2; # public network interface try_files $uri @app; } location / { try_files $uri/index.html $uri @app; } location @app { proxy_pass http://aaa-rails; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Origin $scheme://$http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Host $host; proxy_redirect off; } location ~* ~/assets/ { try_files $uri @app; } listen 80; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/www.meaaa.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/www.meaaa.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }
bbb.me.com站点配置
upstream bbb-rails { server bbb:3000; } server { server_name bbb.me.com bbb-source.me.com bbb.meinternal.com; root /var/www/bbb-rails/public; index index.html index.htm; client_max_body_size 50m; location / { try_files $uri @app; } location @app { proxy_pass http://bbb-rails; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header Origin $scheme://$http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Host $host; proxy_redirect off; } location ~* ~/assets/ { try_files $uri @app; } listen 80; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/bbb.me.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/bbb.me.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }
我的疑惑
之前用非Docker环境的Nginx托管多Rails站点多年,从没遇到过这种问题。而且域名都是正确配置的,不是默认站点的问题(因为两个站点都能被识别,只是内容串位);静态资源正常说明Nginx能正确识别请求域名,只有上游代理的路由出了问题。日志里也没看到报错,也没开启任何缓存机制,重启Nginx能临时解决但几小时后又复发。
真心希望各位能给点排查思路,比如Nginx的哪些内部机制可能导致这种问题?Docker网络层面有没有需要检查的点?
备注:内容来源于stack exchange,提问作者EK0
相关产品推荐
相关产品推荐

