Docker环境下Nginx反向代理Laravel WebSocket连接失败排查
问题排查与修复方案
优先级1:修复Websocket服务无法直连的问题
IP+端口直连失败说明问题根源在Websocket服务本身,优先解决:
- 进入PHP容器检查服务状态:
执行docker exec -it zagreus-melodi bash进入容器,运行supervisorctl status查看laravel-websockets进程状态,如果状态为FATAL/EXITED,直接查看对应supervisor日志排查启动错误,常见原因包括PHP扩展缺失、.env配置无效、项目目录权限不足。 - 检查服务监听地址:
如果进程状态正常,在容器内执行ss -tulpn | grep 6001查看端口监听规则。Laravel Websockets默认仅监听127.0.0.1回环地址,同Docker网络的Nginx容器、外部服务器都无法访问该地址,必须让服务监听0.0.0.0。
修复方式:在项目.env文件中新增配置LARAVEL_WEBSOCKETS_HOST=0.0.0.0,重启Websocket服务后再次检查监听规则,确认显示0.0.0.0:6001后,再尝试用公网IP+6001端口访问,正常会返回WebSocket握手相关响应。 - 排查端口不一致问题:
你提供的Nginx报错日志中upstream地址为172.19.0.5:3030,和配置中写的php:6001完全不符,说明当前Nginx加载的配置不是你贴出的版本。执行docker exec <你的Nginx容器名> nginx -T打印所有加载的Nginx配置,删除其他冗余的反向代理规则,确认upstream端口为6001后,执行docker exec <你的Nginx容器名> nginx -s reload重载配置。
优先级2:修正Nginx反向代理配置
你当前使用的map+命名location匹配逻辑存在路径匹配错误风险,且超时配置不符合长连接要求,直接替换server块内的location规则如下:
# 保留原有map、upstream、server基础配置(监听端口、证书、根目录、server_name等) # 前缀匹配所有Websocket请求路径,Laravel Websockets默认WS请求均以/app开头 location /app/ { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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_set_header X-Forwarded-Proto $scheme; # 调整长连接超时,避免Nginx主动断开空闲WS连接 proxy_read_timeout 86400; proxy_send_timeout 86400; proxy_redirect off; } # 普通Web请求规则 location / { try_files $uri $uri/ /index.php?$query_string; gzip_static on; } # PHP解析规则保留原有配置即可 location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; }
删除原有@web、@ws命名location,以及location /中跳转到命名location的try_files规则,直接前缀匹配WS路径是稳定性最高的配置方式。
其他配置校验项
- 检查.env中PUSHER相关参数:走HTTPS反向代理时,
PUSHER_SCHEME设为https,PUSHER_HOST填你的服务域名,PUSHER_PORT设为443,LARAVEL_WEBSOCKETS_PORT=6001,前端JS初始化参数和.env保持一致,不要硬编码端口。 - SSL终止统一放在Nginx层处理,不要在
websockets.php中配置local_cert、local_pk参数,PHP容器内的Websocket服务跑明文WS即可,双层SSL配置会导致协议不匹配连接失败。 - 检查Nginx配置中server_name拼写,你提供的日志中出现
site.cpm笔误,避免错误请求命中默认server块。
验证流程
- 容器内确认WS服务监听0.0.0.0:6001,本地curl 127.0.0.1:6001返回握手响应
- 公网IP+6001端口直连连通正常
- 重载Nginx配置后用域名发起WS连接,查看Nginx错误日志无upstream连接报错,可通过
/laravel-websockets后台面板查看连接数确认服务正常。
内容的提问来源于stack exchange,提问作者Mehrab HP
相关产品推荐
相关产品推荐

