Docker环境下Laravel跨容器连接其他应用MySQL报连接被拒
Docker 跨Compose项目连接MySQL 连接拒绝问题解决方案
之前两次配置错误的核心原因
- 初始配置用
127.0.0.1:6306的问题:
配置写在mobile应用的PHP容器环境中,127.0.0.1指向的是PHP容器自身的回环地址,不是宿主机。你把resident的MySQL端口映射到宿主机6306,这个端口仅在宿主机网络命名空间生效,容器内部直接访问127.0.0.1根本碰不到这个端口,必然连接拒绝。 - 参考网络方案后仍失败的问题:
- 主机名写错:resident应用compose里的MySQL服务名就是
mysql,容器名是resident-backend-mysql,不存在mysql1这个服务,Docker内置DNS无法解析 - 外部网络名大概率写错:Docker Compose自动创建的网络命名规则是
<项目目录名>_<compose内定义的网络名>,你写的residentbackend_resident和实际网络名不匹配的话,容器根本无法加入目标网络 - 端口用错:容器间走内部Docker网络通信时,不经过宿主机端口映射,必须用MySQL容器内部服务端口3306,不能用宿主机映射的6306
- 主机名写错:resident应用compose里的MySQL服务名就是
分步修复操作
1. 确认resident应用的真实网络名
在部署resident应用的主机上执行命令,列出所有Docker网络:
docker network ls
在输出结果里找到resident项目对应的bridge网络,名字格式类似resident-backend_resident(前缀是你存放resident项目docker-compose.yml的文件夹名),完整记录这个名字,不要自行猜测。
2. 修正mobile应用的docker-compose配置
首先修改networks段,外部网络名必须和上一步查到的完全一致:
networks: laravel: driver: bridge resident-backend_resident: # 替换为你实际查到的resident网络全名 external: true
然后修改php服务的网络配置,把外部网络加入PHP服务的网络列表(不需要给nginx服务加,数据库请求由PHP容器发起):
php: # 其余原有配置保持不变 networks: - laravel - resident-backend_resident # 和上面定义的外部网络名保持一致
修改完成后重建PHP容器让网络配置生效:
docker compose up -d php
容器启动后验证网络是否挂载成功:
docker inspect mobile-server-php | grep Networks -A 20
输出的网络列表中必须包含你配置的resident外部网络,没出现就回去核对网络名是否拼写错误。
3. 修正mobile应用.env的数据库连接配置
跨容器内部通信走Docker DNS,注意两个核心配置:
- 主机名填resident项目里MySQL的服务名
mysql,如果服务名解析失败就直接用MySQL容器名resident-backend-mysql - 端口填MySQL容器内部端口
3306,不要用宿主机映射的6306
正确配置参考:
DB_RESIDENT_HOST=mysql # 解析失败就替换为resident-backend-mysql DB_RESIDENT_PORT=3306 DB_RESIDENT_DATABASE=你的resident业务库名 DB_RESIDENT_USERNAME=你的resident库账号 DB_RESIDENT_PASSWORD=你的resident库密码
4. 清除Laravel缓存后验证
Laravel会缓存配置文件,修改.env后必须进入PHP容器清除缓存,否则旧配置不会生效:
docker exec -it mobile-server-php php artisan config:clear docker exec -it mobile-server-php php artisan cache:clear
清完再调用测试接口即可正常连接。
兜底排查方案
如果按上述步骤操作后仍连接失败,先进入mobile的PHP容器直接用mysql客户端测试连接,排除Laravel配置干扰:
docker exec -it mobile-server-php bash # 进入容器后执行连接命令,替换为你自己的账号密码库名 mysql -h mysql -P3306 -u你的库账号 -p你的库密码 你的库名
- 如果命令行连接也失败:检查resident的MySQL容器是否正常运行,是否配置了bind-address为127.0.0.1(官方MySQL镜像默认是0.0.0.0允许所有地址连接,一般不会有这个问题),确认两个容器在同一个Docker网络下
- 如果命令行能正常连接:说明Laravel配置缓存没清干净,或者config/database.php里的resident_mysql连接配置有拼写错误,逐行核对即可。
不要尝试用host.docker.internal绕宿主机访问,这种方式受宿主机防火墙、转发规则影响,稳定性远低于直接走Docker内部网络通信。
内容的提问来源于stack exchange,提问作者simpsons3
相关产品推荐
相关产品推荐

