hyperf 在 docker 中实现多数据库连接需通过服务名而非 ip 地址通信,配置中 host 必须设为 docker-compose.yml 定义的服务名(如 mysql57、mysql80),并配合环境变量动态管理连接参数,且 mysql 5.7 与 8.0 需独立连接池及适配 pdo 选项。

Hyperf 在 Docker 环境中实现多数据库连接,关键不是改容器内 IP 地址,而是通过环境变量 + 配置文件联动,让每个数据库连接名(如 mysql_v57、mysql_v80)指向正确的服务地址和端口。Docker 内部网络靠服务名通信,不是写 127.0.0.1 或宿主机 IP。
数据库服务名要与 docker-compose.yml 中定义的一致
Docker 容器间通过服务名自动 DNS 解析。比如你在 docker-compose.yml 里定义了两个 MySQL 实例:
-
mysql57:对应 MySQL 5.7,服务名就是mysql57 -
mysql80:对应 MySQL 8.0,服务名就是mysql80
Hyperf 应用容器里访问它们,直接用 mysql57:3306 和 mysql80:3306,不需要加 http://,也不用填宿主机 IP。
config/autoload/databases.php 中按连接名配置 host
每个连接的 host 字段必须填对应的服务名(不是 localhost),例如:
'mysql_v57' => [
'driver' => 'mysql',
'host' => 'mysql57', // ← 这里填服务名,不是 127.0.0.1
'port' => 3306,
'database' => 'db_v57',
'username' => 'hyperf',
'password' => 'hyperf123',
// ... 其他参数
],
'mysql_v80' => [
'driver' => 'mysql',
'host' => 'mysql80', // ← 同样填服务名
'port' => 3306,
'database' => 'db_v80',
'username' => 'hyperf',
'password' => 'hyperf123',
// ...
],
这样运行时调用 Db::connection('mysql_v57') 就会连上 mysql57 容器,Db::connection('mysql_v80') 则连另一个。
环境变量控制不同环境下的地址切换
推荐把 host/port/database 等动态值抽成环境变量,在 databases.php 中读取:
- 在
docker-compose.yml的app服务下声明:
environment: - DB_V57_HOST=mysql57 - DB_V57_PORT=3306 - DB_V80_HOST=mysql80 - DB_V80_PORT=3306
- 然后在
databases.php中使用env()获取:
'mysql_v57' => [
'host' => env('DB_V57_HOST', 'mysql57'),
'port' => (int)env('DB_V57_PORT', 3306),
// ...
],
好处是开发、测试、生产可共用同一份配置文件,只换 .env 或 compose 的 environment 即可。
注意跨版本连接池不能复用
MySQL 5.7 和 8.0 认证方式、SQL 模式不同,Hyperf 不允许共用一个连接池。必须为它们分别配置独立连接名,并在 pool 子项中显式设置:
enable_pool => true-
min_connections/max_connections按各自实例实际承载力设(比如 MySQL 5.7 实例 max_connections=200,连接池 max_connections 建议 ≤150) - 必要时补
options:MySQL 8.0 加PDO::MYSQL_ATTR_SSL_MODE => PDO::SSL_NONE,5.7 可能需PDO::ATTR_EMULATE_PREPARES => true
否则容易出现 handshake 失败、prepared statement 报错或 Too many connections。











