本质是docker容器间网络不通导致dns解析失败,需确保hyperf与数据库容器同属一个自定义网络、db_host填服务名而非localhost、mysql监听0.0.0.0并授权%用户、连接端口为容器内暴露端口。

Hyperf 应用在 Docker 容器中连接数据库失败,报错 SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Try again,本质是容器无法解析或访问数据库服务地址。这不是 Hyperf 框架特有问题,而是典型的 Docker 网络通信配置缺失。核心在于让 PHP 应用容器和数据库容器处于可互通的网络环境,并确保连接参数匹配该环境。
确认数据库服务名与网络归属一致
Hyperf 的 .env 或配置文件中,数据库 DB_HOST 必须填写 Docker Compose 中定义的服务名(如 mysql 或 db),不能写 localhost 或 127.0.0.1——那在容器内指向自己,而非数据库容器。
- 检查
docker-compose.yml是否为所有服务声明了同一自定义网络(推荐显式定义,避免依赖默认网络) - 确保
hyperf和mysql(或其他 DB)服务都加入了该网络,例如:networks: - app-network - 运行
docker compose ps确认两个服务状态均为running
验证容器内 DNS 解析是否正常
Docker 默认为同一网络内的服务提供内置 DNS,可通过服务名自动解析 IP。若解析失败,getaddrinfo failed 就会直接出现。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 进入 Hyperf 容器:
docker compose exec hyperf bash - 执行:
nslookup mysql(把mysql替换为你实际的服务名) - 若返回有效 IP(如
172.20.0.3),说明 DNS 正常;若超时或报server can't find,说明网络未连通或服务名不匹配 - 也可试
ping mysql -c 3,进一步确认连通性
检查数据库监听地址与权限配置
即使网络通了,MySQL/MariaDB 默认只监听 localhost,拒绝来自其他容器的连接。
- 进入数据库容器:
docker compose exec mysql bash - 登录 MySQL:
mysql -u root -p,执行:SELECT host, user FROM mysql.user;—— 确认用户允许从%或具体容器网段(如172.20.%)连接 - 修改绑定地址:编辑
/etc/mysql/my.cnf(或对应配置文件),将bind-address = 127.0.0.1改为bind-address = 0.0.0.0,然后重启 MySQL 服务 - 执行
FLUSH PRIVILEGES;生效权限变更
排除端口与防火墙干扰
Hyperf 连接字符串中的端口(如 :3306)必须与数据库容器暴露的内部端口一致,而非宿主机映射端口。
- 数据库服务定义中应使用
expose:(仅内部暴露)或ports:(映射到宿主机),但 Hyperf 连接时始终用expose端口 - 例如:
mysql:下写expose: ["3306"],Hyperf 配置DB_PORT=3306即可 - 宿主机防火墙(如 ufw、firewalld)一般不影响容器间通信,但若使用
host网络模式则需检查 - 避免在开发中误用
--network host:它绕过 Docker 网络栈,导致DB_HOST=localhost反而可能生效,但破坏隔离且不可移植










