Docker环境PHP连接MySQL报SQLSTATE[HY000][2002]错误求助
Docker环境下PHP连接MySQL的问题排查与解决
核心问题修正:容器间通信的端口与主机配置
你的PHP连接字符串存在两个关键错误:
- 容器间通信时,不能使用宿主机映射的端口3311,必须用MySQL容器的内部端口
3306 - 连接主机应使用docker-compose中定义的服务名
database,而非localhost(localhost在PHP容器内指向自身,而非MySQL容器)
修正后的PHP连接代码:
<?php $usr = "gexpenses"; $pwd = "1234"; try { // 修正host为服务名database,端口为内部端口3306 $pdo = new PDO("mysql:host=database;port=3306;dbname=gexpenses", $usr, $pwd); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch (PDOException $e) { echo "Connection failed: " . $e->getMessage(); }
若仍报Connection refused的排查步骤
1. 确认MySQL容器是否正常启动
执行命令查看MySQL容器日志,检查是否有启动错误或初始化失败:
docker-compose logs database
重点关注日志中是否出现ready for connections字样,若使用了初始化脚本bd.sql,需确认脚本无语法错误。
2. 检查数据库用户权限
进入MySQL容器,验证gexpenses用户是否允许跨容器连接:
# 进入MySQL容器 docker-compose exec database mysql -uroot -p12345 # 执行SQL查看用户权限范围 SELECT user, host FROM mysql.user WHERE user = 'gexpenses';
若host字段为localhost,则该用户仅能在MySQL容器内部访问,需修改权限:
GRANT ALL PRIVILEGES ON gexpenses.* TO 'gexpenses'@'%'; FLUSH PRIVILEGES;
3. 确认MySQL监听地址
在MySQL容器内,检查MySQL是否监听所有网络接口(而非仅本地回环):
docker-compose exec database netstat -tulpn | grep 3306
输出应包含0.0.0.0:3306,若为127.0.0.1:3306,需修改MySQL配置:
- 在docker-compose.yml的
database服务中添加自定义配置挂载:volumes: - ./my.cnf:/etc/mysql/conf.d/custom.cnf:ro - 创建
my.cnf文件,内容为:[mysqld] bind-address = 0.0.0.0 - 重启容器:
docker-compose restart database
4. 等待MySQL初始化完成
MySQL容器启动后,执行初始化脚本和数据准备需要时间,若PHP容器启动过快,会出现连接拒绝。可通过以下方式解决:
- 在docker-compose.yml中为
database服务添加健康检查:database: # 其他配置... healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p12345"] interval: 5s timeout: 5s retries: 5 - 在
web服务中添加依赖,等待database健康后启动:web: # 其他配置... depends_on: database: condition: service_healthy
内容的提问来源于stack exchange,提问作者Jethrotul
相关产品推荐
相关产品推荐

