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

Apache如何将多应用反向代理至非根路径(/)?

Apache如何将多应用反向代理至非根路径(/)?

这个问题太常见啦!我刚接触反向代理的时候也踩过一模一样的坑~核心问题在于你代理的这几个应用(Node-RED、Jupyter、pgAdmin)默认都认为自己是跑在网站根目录(/)下的,它们生成的页面链接、静态资源路径全都是基于/来写的。比如Node-RED会在页面里请求/red/xxx这样的资源,当你把它代理到/nodered/后,浏览器会直接去http://127.0.0.1/red/xxx找资源,而不是http://127.0.0.1/nodered/red/xxx,自然就会出现404或者页面加载异常的情况。

下面给你两种解决思路,优先推荐第一种,更稳妥:


思路一:让应用自身适配子路径(最可靠)

大部分现代应用都支持设置「基础路径(Base URL)」,告诉应用它实际运行在网站的某个子路径下,这样应用生成的所有链接、资源路径都会自动带上这个前缀,和Apache的代理配置完美匹配。

针对你的三个应用的具体配置:

  1. Node-RED

    • 找到它的配置文件settings.js(默认路径是~/.node-red/settings.js,系统安装的话可能在/etc/node-red/下)
    • 找到httpAdminRoot这一行,修改成:
      httpAdminRoot: "/nodered",
      
    • 重启Node-RED服务,然后Apache的配置可以写成:
      <Location "/nodered/">
          ProxyPass http://127.0.0.1:1880/nodered/
          ProxyPassReverse http://127.0.0.1:1880/nodered/
      </Location>
      
  2. Jupyter Notebook

    • 启动时直接加参数指定基础路径:
      jupyter notebook --NotebookApp.base_url='/jupyter'
      
    • 或者生成永久配置文件修改:先执行jupyter notebook --generate-config,然后在生成的jupyter_notebook_config.py里找到c.NotebookApp.base_url,设置为:
      c.NotebookApp.base_url = '/jupyter'
      
    • Apache配置要注意加上WebSocket支持(Jupyter实时交互需要):
      <Location "/jupyter/">
          ProxyPass http://127.0.0.1:8888/jupyter/
          ProxyPassReverse http://127.0.0.1:8888/jupyter/
          # 支持WebSocket
          ProxyPass ws://127.0.0.1:8888/jupyter/ ws://127.0.0.1:8888/jupyter/
          ProxyPassReverse ws://127.0.0.1:8888/jupyter/ ws://127.0.0.1:8888/jupyter/
      </Location>
      
  3. pgAdmin

    • 如果是本地安装的pgAdmin,在它的配置目录(比如/var/lib/pgadmin/或者用户目录下的.pgadmin/)创建config_local.py,添加:
      SERVER_BASE_URL = '/pgadmin/'
      
    • 如果是Docker部署的,直接加环境变量:PGADMIN_CONFIG_SERVER_BASE_URL="/pgadmin/"
    • 重启pgAdmin后,Apache配置:
      <Location "/pgadmin/">
          ProxyPass http://127.0.0.1:5433/pgadmin/
          ProxyPassReverse http://127.0.0.1:5433/pgadmin/
      </Location>
      

思路二:用Apache的mod_proxy_html重写响应路径(通用但有局限)

如果不想修改应用的配置,可以用Apache的mod_proxy_html模块来自动重写应用响应内容里的根路径,把所有/开头的路径替换成对应的子路径。

步骤:

  1. 先启用必要的Apache模块:
    a2enmod proxy proxy_http proxy_html xml2enc
    
  2. 修改Apache的虚拟主机配置:
    <VirtualHost *:80>
        ServerName 127.0.0.1
    
        # 开启HTML重写功能
        ProxyHTMLEnable On
        ProxyHTMLDoctype XHTML Strict
    
        <Location "/nodered/">
            ProxyPass http://127.0.0.1:1880/
            ProxyPassReverse http://127.0.0.1:1880/
            # 把响应里的/替换成/nodered/
            ProxyHTMLURLMap / /nodered/
        </Location>
    
        <Location "/jupyter/">
            ProxyPass http://127.0.0.1:8888/
            ProxyPassReverse http://127.0.0.1:8888/
            ProxyHTMLURLMap / /jupyter/
            # 同样要支持WebSocket
            ProxyPass ws://127.0.0.1:8888/ ws://127.0.0.1:8888/
            ProxyPassReverse ws://127.0.0.1:8888/ ws://127.0.0.1:8888/
        </Location>
    
        <Location "/pgadmin/">
            ProxyPass http://127.0.0.1:5433/
            ProxyPassReverse http://127.0.0.1:5433/
            ProxyHTMLURLMap / /pgadmin/
        </Location>
    </VirtualHost>
    
  3. 重启Apache服务生效。

注意:

这个方案的局限性在于,有些应用会用JavaScript动态生成路径(比如前端框架渲染的页面),mod_proxy_html可能没法完全捕获并重写这些动态路径,导致部分功能异常。所以如果用这个方案遇到问题,还是优先回到思路一,修改应用自身的基础路径配置。


总结一下:没有完全通用的“一键解决”方案,因为不同应用对路径的处理逻辑不同,但大部分应用都支持设置基础路径,这是最稳妥的解决方式;如果实在不想改应用,再用Apache的重写工具来补,但要做好调试准备。

备注:内容来源于stack exchange,提问作者raylight

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 09:07:39