Docker Compose中MySQL容器主机连接报Reading initial communication packet错误
我之前也碰到过一模一样的情况:单独启动MySQL容器能正常连接,换成Compose部署就弹出ERROR 2013的连接丢失错误。结合你的配置和问题描述,咱们一步步排查解决:
1. 先排查端口占用情况
首先确认主机的3306端口有没有被其他进程抢占(比如本地安装的MySQL、其他服务)。在主机终端执行:
# 用netstat检查端口占用 netstat -tulpn | grep 3306 # 或者用更现代的ss命令 ss -tulpn | grep 3306
如果输出里有非Docker的进程占用3306,要么停止该进程,要么修改Compose的端口映射,比如改成:
ports: - 3307:3306
之后用新端口测试连接:
mysql -u root -proot -h 127.0.0.1 -P 3307 --protocol=tcp
2. 清理冲突的环境变量
你的Compose配置里设置了MYSQL_USER: root,这是个关键问题——MYSQL_USER是用来创建额外普通用户的,而root是MySQL默认的超级用户,重复设置会触发初始化逻辑冲突,甚至破坏权限配置。
删掉这个多余的环境变量,修改后的配置片段:
environment: MYSQL_DATABASE: some_mysql # 移除下面这行 # MYSQL_USER: root MYSQL_PASSWORD: root MYSQL_ROOT_PASSWORD: root
注意:如果./mysql/data数据卷已经存在(之前容器创建过),MySQL初始化脚本不会重新运行,建议先备份数据,再删除卷重启:
# 备份数据(可选但推荐) docker cp some_mysql:/var/lib/mysql ./mysql/data_backup # 删除容器和关联数据卷 docker-compose down -v # 重新启动服务 docker-compose up -d
3. 确认MySQL绑定的地址
有时候数据卷里的MySQL配置文件可能被修改过,导致bind-address设为127.0.0.1(仅允许容器内访问)。进入容器检查配置:
docker exec -it some_mysql bash # 查看配置文件(不同版本路径可能略有差异) cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep bind-address
如果输出是bind-address = 127.0.0.1,需要改成0.0.0.0(允许所有IP访问)。最简单的方式是在Compose里添加启动命令强制设置:
services: mysql: # ...其他配置 command: --bind-address=0.0.0.0
重启容器后再测试连接。
4. 检查防火墙/安全组规则
如果主机启用了防火墙(比如ufw、iptables),确保允许本地访问3306端口:
# 针对ufw防火墙 sudo ufw allow 3306/tcp # 临时关闭防火墙测试(不推荐长期关闭) sudo ufw disable
测试连接恢复后,再按需调整防火墙规则。
5. 用容器IP直接测试(排查网络映射问题)
如果以上步骤都无效,先获取容器的IP地址:
docker inspect some_mysql | grep -A 2 "IPAddress"
然后用容器IP直接连接:
mysql -u root -proot -h <容器IP> -P 3306
如果能连上,说明是Docker端口映射异常,尝试重启Docker服务:
sudo systemctl restart docker
按照这些步骤排查,应该能解决你的连接问题。
内容的提问来源于stack exchange,提问作者sr9yar

