ThinkPHP6容器中数据库连接需将hostname设为MySQL容器服务名(如db)或宿主机IP,不可用localhost;同时MySQL须配置bind-address=0.0.0.0并授权远程用户,否则连接失败。

因为容器里的 localhost 指的是它自己,不是宿主机,更不是你部署的 MySQL 容器。
容器网络是隔离的,localhost 不跨容器
Docker 默认为每个容器分配独立的网络命名空间。你在 ThinkPHP6 的 database.php 里写 hostname => 'localhost',PHP 进程就会尝试连接本容器的 127.0.0.1:3306 —— 可这个地址上根本没运行 MySQL 服务。
- 宿主机上的 MySQL:运行在物理机或虚拟机的 127.0.0.1,对容器不可见
- 另一个 MySQL 容器:运行在独立 IP(如 172.20.0.2),需用服务名访问
- localhost 在容器内永远只指向自身,无法“穿透”到其他容器或宿主机
正确写法取决于你的部署方式
不是统一改成某个固定值,而是看 MySQL 是怎么部署的:
-
MySQL 也在 Docker 中(推荐,如 docker-compose):host 填
db或mysql等你在docker-compose.yml中定义的服务名(大小写敏感) -
MySQL 装在宿主机上(非容器):Windows/macOS 可用
host.docker.internal;Linux 需加--add-host=host.docker.internal:host-gateway或直接填宿主机局域网 IP(如 192.168.1.100) - 不建议用 127.0.0.1 替代 localhost:在容器里它和 localhost 效果一样,仍指向自己
光改 host 还不够,MySQL 侧也要配合
即使 PHP 容器连对了地址,宿主机或 MySQL 容器本身也可能拒绝连接:
立即学习“PHP免费学习笔记(深入)”;
- 检查 MySQL 配置文件,确保
bind-address = 0.0.0.0(不是 127.0.0.1) - 确认用户权限允许远程连接:
CREATE USER 'tp_user'@'%' IDENTIFIED BY 'pwd'; GRANT ALL ON mydb.* TO 'tp_user'@'%'; FLUSH PRIVILEGES; - 若用 MySQL 8.0+,注意认证插件默认是
caching_sha2_password,ThinkPHP6 可能不兼容,建用户时指定IDENTIFIED WITH mysql_native_password
验证是否配置生效的小技巧
进入 PHP 容器终端,手动测试连接,比等应用报错更快定位问题:
- 装
mysql-client:运行apt-get update && apt-get install -y mysql-client(Debian/Ubuntu) - 执行命令:
mysql -h db -P 3306 -u root -p(把db换成你实际的服务名) - 如果连不上,错误信息会明确提示是 DNS 解析失败、连接被拒,还是认证失败



















