Laravel Docker环境下Artisan与Model数据库连接冲突问题排查
问题原因分析
- 当
DB_HOST=127.0.0.1时:- 宿主机执行
php artisan migrate:MySQL容器已将3306端口映射到宿主机,宿主机的127.0.0.1可直接访问到MySQL服务,因此命令正常运行。 - 容器内的Laravel应用:容器自身的
127.0.0.1指向容器本身,而非宿主机,无法连接到MySQL容器,触发连接拒绝错误。
- 宿主机执行
- 当
DB_HOST=mysql时:- 容器内的Laravel应用:Docker的
sail网络会自动将服务名称mysql解析为对应容器的IP,因此能正常连接MySQL加载数据。 - 宿主机执行
php artisan migrate:宿主机DNS系统无法识别mysql这个主机名,无法解析对应地址,导致连接失败。
- 容器内的Laravel应用:Docker的
解决方法
方法一:使用Laravel Sail容器内执行命令
直接通过Sail在Laravel容器内运行迁移命令,命令与应用处于同一Docker网络环境,使用mysql作为DB_HOST即可正常工作:
sail artisan migrate
这是最适配Docker开发环境的方案,无需修改任何配置。
方法二:修改宿主机hosts文件解析mysql
在宿主机hosts文件中添加映射,让宿主机将mysql解析到127.0.0.1:
- Linux/macOS:编辑
/etc/hosts,添加127.0.0.1 mysql - Windows:编辑
C:\Windows\System32\drivers\etc\hosts,添加127.0.0.1 mysql
修改后,无论容器内应用还是宿主机执行php artisan migrate,使用DB_HOST=mysql都能正常连接。
方法三:区分环境配置
创建两个环境配置文件,分别适配宿主机和容器环境:
- 宿主机使用
.env.local,设置DB_HOST=127.0.0.1 - 容器内使用
.env,设置DB_HOST=mysql
执行宿主机命令时指定环境文件:
php artisan migrate --env=local
生产环境情况
生产环境不会出现此类问题,原因如下:
- 若采用Docker部署,Laravel与MySQL会处于同一自定义Docker网络中,直接使用MySQL服务名作为
DB_HOST即可;且生产环境不会在宿主机直接执行artisan命令,而是进入容器内运行,或通过CI/CD流程在容器环境执行迁移。 - 若使用云数据库(如RDS、云数据库MySQL),只需将
DB_HOST配置为云数据库的内网/公网地址,不存在本地与容器的网络差异问题。
内容的提问来源于stack exchange,提问作者sheikhamir
相关产品推荐
相关产品推荐

