Laravel+Docker环境下DB_HOST配置冲突问题及解决方案咨询
Laravel Docker环境下DB_HOST配置冲突问题解决
问题背景
按照Laravel官方文档搭建带Docker的Laravel项目后,遇到.env文件中DB_HOST配置冲突:
- 执行
php artisan migrate:fresh等Artisan命令时,DB_HOST需设为127.0.0.1或localhost才能正常运行; - 通过浏览器访问项目(
localhost)展示数据时,DB_HOST需设为mysql,否则会出现连接被拒绝的错误。
相关配置:
.env文件片段
DB_CONNECTION=mysql DB_HOST=127.0.0.1 || localhost || mysql(?) DB_PORT=3306 DB_DATABASE=tutorial DB_USERNAME=sail DB_PASSWORD=password
数据库配置(config/database.php)片段
'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ],
为什么浏览器访问时需要设为mysql?
这是Docker容器的网络特性决定的:
- 本地终端执行Artisan命令时,命令是在宿主机环境运行的,要访问Docker里的MySQL服务,得通过宿主机的端口映射(比如3306端口),所以用
127.0.0.1或localhost指向宿主机,再转发到MySQL容器。 - 浏览器访问项目时,实际运行代码的是Laravel所在的Docker容器,容器之间通过Docker内部网络通信,
mysql是Docker Compose配置中MySQL服务的名称(容器名),Docker内部DNS会把这个名称解析到对应的MySQL容器IP,所以必须用mysql作为主机名才能让Laravel容器连接到MySQL容器。
如何同时适配两种场景?
有两种实用方案:
方案1:用Docker内部命令执行Artisan
直接进入Laravel容器内部执行命令,此时容器内环境和浏览器访问时一致,DB_HOST设为mysql即可通用:
# 进入Laravel容器(服务名根据你的docker-compose.yml调整) ./vendor/bin/sail shell # 在容器内执行迁移 php artisan migrate:fresh
或者用Sail快捷命令一步完成:
./vendor/bin/sail artisan migrate:fresh
方案2:创建多环境配置文件
复制.env文件为.env.local,专门用于本地终端执行命令:
.env(容器运行用):DB_HOST=mysql.env.local(本地终端用):DB_HOST=127.0.0.1
执行Artisan命令时指定使用本地配置:
php artisan migrate:fresh --env=local
或者临时设置环境变量执行:
DB_HOST=127.0.0.1 php artisan migrate:fresh
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

