You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

nginx proxy_pass同域名反代多Docker容器子路径访问失败问题

问题排查结果

当前配置存在4个核心问题,导致子路径代理失败:

  • 路径匹配规则覆盖不全:现有location /dboard/规则仅能匹配/dboard/xxx这类带后续路径的请求,直接访问/dboard(无尾斜杠)时不会命中该规则,请求会被转发到根路径的Flask服务,触发404。
  • 后端Bokeh未做子路径适配:Bokeh默认以根路径/为服务根,生成的静态资源引用、接口、WebSocket请求地址全是根路径,且无法识别/dboard前缀的请求,就算Nginx转发正确,资源也会全部请求到Flask服务上,加载失败。
  • 缺少WebSocket代理配置:Bokeh的交互功能、实时数据更新依赖WebSocket连接,现有配置未做协议升级支持,会导致连接中断,触发502或功能失效。
  • 路径转发逻辑不匹配:如果Bokeh未配置子路径前缀,转发时需要剥离/dboard前缀;如果配置了子路径前缀,则需要原样转发路径,之前调整尾斜杠无效就是因为没有和Bokeh的配置对应上。
修复步骤

1. 修改dashboard服务启动配置

编辑docker-compose-local.yaml,给Bokeh启动命令添加子路径前缀和跨域WebSocket允许配置,让Bokeh原生适配/dboard子路径部署,不需要Nginx做响应内容替换,稳定性最高:

dashboard:
    image: timh-urban-vprm-dashboard:latest
    # 原有命令后追加两个参数:--prefix指定子路径,--allow-websocket-origin允许Nginx地址的WebSocket连接
    command: mamba run --no-capture-output -n venv-urbanVPRM python urban_vprm_dashboard.py --prefix /dboard --allow-websocket-origin=localhost:1337
    expose:
      - 8002
    # 不需要对外直接暴露Bokeh端口的话可以删掉下面的ports配置,减少对外暴露面
    ports:
      - 8002:8002

注意:如果你的urban_vprm_dashboard.py是手动初始化bokeh.server.server.Server实例,需要在初始化参数中添加prefix='/dboard'和allow_websocket_origin=['localhost:1337'],命令行参数优先级低于代码内配置。

2. 调整Nginx配置

编辑nginx.conf,修正路径匹配规则,添加WebSocket支持,修改后完整配置如下:

upstream site {
    server website:8000;
}

upstream dboard {
    server dashboard:8002;
}

server {
    listen 80;
    server_name 0.0.0.0;

    # 通用代理配置抽离,避免重复书写
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;

    location / {
        proxy_pass http://site;
    }

    # ^~修饰符保证该路径优先级高于普通正则匹配,覆盖所有/dboard开头的请求
    location ^~ /dboard {
        # 注意:此处末尾不要加斜杠!需要将带/dboard前缀的路径原样转发给已经配置了prefix的Bokeh服务
        proxy_pass http://dboard;

        # Bokeh必需的WebSocket配置
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        # 关闭代理缓冲,避免Bokeh实时消息推送卡顿
        proxy_buffering off;
    }
}
验证流程
  1. 执行docker-compose -f docker-compose-local.yaml down清理旧容器,避免旧配置缓存影响
  2. 执行docker-compose -f docker-compose-local.yaml up -d --build重新构建启动服务栈
  3. 先验证Bokeh自身配置生效:访问http://localhost:8002/dboard,确认可以正常打开仪表盘
  4. 再验证Nginx代理:访问http://localhost:1337/dboard,确认仪表盘正常加载、交互功能无报错,同时http://localhost:1337的Flask服务访问正常。
常见问题排查
  • 如果访问/dboard返回404:进入Nginx容器执行curl http://dashboard:8002/dboard,确认容器内部网络能正常访问Bokeh的带前缀路径,排除容器间网络不通的问题;如果容器内访问也404,说明Bokeh的prefix参数未生效,检查启动命令或代码内的Server初始化配置。
  • 如果仪表盘页面加载但交互功能报错:打开浏览器F12控制台查看WebSocket请求地址,确认是ws://localhost:1337/dboard/...格式,如果地址是根路径的ws://localhost:1337/ws/...,还是Bokeh的prefix配置未生效。
  • 如果返回502错误:检查dashboard服务是否正常启动,是否监听在0.0.0.0:8002地址,不要绑定127.0.0.1导致容器内无法访问。

内容的提问来源于stack exchange,提问作者Timothy W. Hilton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:01:13