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

Apache反向代理连接Docker容器内WebSocket服务器故障排查求助

Apache反向代理Docker容器内WebSocket服务器连接失败排查方案

问题场景

  • WebSocket服务器部署在Docker容器内,监听带动态后缀的路径(如/ws/chat/1694406657943/)
  • 配置Apache作为反向代理,将WebSocket请求转发至容器内服务器
  • 尝试连接ws://abc.com/ws/chat/1694406657943/时,出现“WebSocket connection failed”错误

已验证操作

  • Docker容器内WebSocket服务器运行正常,可处理指定路径的连接请求
  • Apache错误日志无相关报错或警告
  • Docker容器端口已正确暴露至宿主机
  • 直接访问宿主机上的WebSocket服务器可正常建立连接

当前Apache配置

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com


        ServerName abc.com
        ServerAdmin webmaster@abc.com

     ProxyRequests Off

     <Proxy *>
        Require all granted
        Allow from all
     </Proxy>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/


    ProxyPass /ws ws://127.0.0.1:8000/
    ProxyPassReverse /ws ws://127.0.0.1:8000/
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/abc.com.error.log
        CustomLog ${APACHE_LOG_DIR}/abc.com.access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

报错截图

WebSocket连接失败错误

排查与解决步骤

1. 启用Apache必要模块

WebSocket反向代理依赖proxy_wstunnel模块,执行以下命令启用并重启Apache:

a2enmod proxy proxy_http proxy_wstunnel
systemctl restart apache2

2. 修正代理规则顺序与路径匹配

当前配置中ProxyPass / http://127.0.0.1:8000/会优先匹配所有请求,导致/ws开头的WebSocket请求无法触发专门的代理规则。调整规则顺序,将更具体的WebSocket代理放在前面,并保证路径末尾斜杠一致:

<VirtualHost *:80>
    ServerName abc.com
    ServerAdmin webmaster@abc.com

    ProxyRequests Off

    <Proxy *>
        Require all granted
    </Proxy>

    ProxyPreserveHost On
    # 优先处理WebSocket请求,保持路径末尾斜杠一致
    ProxyPass /ws/ ws://127.0.0.1:8000/ws/
    ProxyPassReverse /ws/ ws://127.0.0.1:8000/ws/

    # 处理其余HTTP请求
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/

    ErrorLog ${APACHE_LOG_DIR}/abc.com.error.log
    CustomLog ${APACHE_LOG_DIR}/abc.com.access.log combined
</VirtualHost>

3. 保留WebSocket握手请求头

添加配置确保Apache不修改WebSocket握手所需的Upgrade和Connection请求头:

ProxyPass /ws/ ws://127.0.0.1:8000/ws/
ProxyPassReverse /ws/ ws://127.0.0.1:8000/ws/
# 强制保留WebSocket握手请求头
RequestHeader set Upgrade %{HTTP:Upgrade}e env=HTTP_UPGRADE
RequestHeader set Connection "upgrade" env=HTTP_UPGRADE

4. 启用详细日志排查

调整Apache日志级别,获取请求转发的详细信息:

LogLevel info proxy:debug

重启Apache后,查看abc.com.access.log和abc.com.error.log,确认WebSocket请求是否正确转发至容器内服务器。

5. 再次验证Docker端口映射

检查容器端口映射是否正确,确保宿主机8000端口映射到容器内WebSocket服务器的监听端口:

docker ps

查看目标容器的PORTS列,确认存在类似0.0.0.0:8000->[容器内端口]/tcp的映射规则。

内容的提问来源于stack exchange,提问作者Shamith Wimukthi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:58:38