phpMyAdmin容器无法连接宿主机MySQL,因容器localhost指向自身而非宿主机;需改用host.docker.internal(Docker Desktop)或宿主机局域网IP,并配置MySQL bind-address=0.0.0.0及对应用户授权。
phpMyAdmin 容器默认无法直接访问宿主机的 MySQL(哪怕宿主机 MySQL 正在监听 0.0.0.0:3306),因为 Docker 容器有自己的网络命名空间,localhost 指向的是容器内部,不是宿主机。
必须显式让 phpMyAdmin 容器能路由到宿主机网络 —— 这是核心前提,其他配置都是在此基础上展开。
用 host.docker.internal 连宿主机 MySQL(推荐,开发环境)
这是 docker desktop(macos/windows)和较新版本 docker engine(linux ≥ 20.10)原生支持的特殊 dns 名称,自动解析为宿主机网关 ip。
启动 phpMyAdmin 时,把 MYSQL_HOST 设为 host.docker.internal:
docker run -d \ --name phpmyadmin \ -p 8080:80 \ -e PMA_HOST=host.docker.internal \ -e PMA_PORT=3306 \ -e PMA_USER=root \ -e PMA_PASSWORD=123456 \ -d phpmyadmin/phpmyadmin
⚠️ 注意:PMA_HOST 是 phpMyAdmin 的环境变量名,不是 MySQL 的;它控制 Web 界面连接哪个后端 MySQL 实例。
- 宿主机 MySQL 必须允许远程连接:确认
bind-address不是127.0.0.1(应为0.0.0.0或注释掉),且用户有'root'@'%'权限 - Linux 上若提示
host.docker.internal解析失败,需手动加--add-host=host.docker.internal:host-gateway - 该方式不适用于生产环境,因暴露宿主机端口且绕过容器网络隔离
把 phpMyAdmin 和 MySQL 放进同一个自定义网络(更安全、可复用)
当两个容器同属一个 docker network,它们可通过容器名直接通信 —— 这是 Docker 推荐的互连方式,无需暴露宿主机端口。
先创建网络并启动 MySQL(带明确容器名):
立即学习“PHP免费学习笔记(深入)”;
docker network create mysql-net docker run -d \ --name mysql-host \ --network mysql-net \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /home/service/mysql/data:/var/lib/mysql \ -v /home/service/mysql/conf/my.cnf:/etc/my.cnf \ -d mysql:8.0
再启动 phpMyAdmin,用 mysql-host 作 PMA_HOST:
docker run -d \ --name phpmyadmin \ --network mysql-net \ -p 8080:80 \ -e PMA_HOST=mysql-host \ -e PMA_PORT=3306 \ -e PMA_USER=root \ -e PMA_PASSWORD=123456 \ -d phpmyadmin/phpmyadmin
-
mysql-host是上面--name指定的名称,Docker 内置 DNS 自动将其解析为对应容器 IP - MySQL 容器无需额外开放
-p映射到宿主机,只要phpMyAdmin在同一网络就能通 - 若 MySQL 启用了
default_authentication_plugin=mysql_native_password(MySQL 8.0 默认是 caching_sha2_password),phpMyAdmin才能正常认证
常见连不上原因和验证步骤
连不上时,别急着改配置,先分层验证:
- 从
phpMyAdmin容器内测试连通性:docker exec -it phpmyadmin ping host.docker.internal或docker exec -it phpmyadmin nc -zv mysql-host 3306 - 确认 MySQL 是否监听正确地址:
docker exec mysql-host ss -tln | grep :3306,输出应含*:3306,而非127.0.0.1:3306 - 检查用户权限:
docker exec -it mysql-host mysql -uroot -p -e "SELECT Host FROM mysql.user WHERE User='root';",确保有%或具体客户端 IP -
phpMyAdmin日志里出现mysqli::real_connect(): (HY000/1045): Access denied,基本是密码错或插件不匹配;出现Connection refused,说明网络或端口不通
为什么不能直接用 172.17.0.1?
有人尝试用 Docker 默认 bridge 网关 IP 172.17.0.1 让容器访问宿主机 MySQL,但这个地址不稳定:
- Docker 可能使用其他子网(如
172.18.0.0/16),取决于系统配置或dockerd启动参数 - 重启 Docker 服务后,bridge 网关 IP 可能变化
- 该地址仅在默认
bridge网络下有效;一旦用了自定义网络(推荐做法),172.17.0.1就失效了
所以硬编码 IP 是脆弱方案,host.docker.internal 或自定义网络 + 容器名才是可维护的选择。



















