基于 Docker 的 PHP 如何连接 MySQL

环境

  • 基于 docker-compose 管理的 PHP 和 MySQL 服务
  • PHP 容器中的程序连接 MySQL 容器中的服务, 采用 PDO 形式

测试代码片段

1
2
3
4
5
6
<?php
try{
$pdo = new PDO('mysql:dbname=test;host=127.0.0.1;charset=utf8mb4;port=3306','root','root');
}catch(PDOException $pe){
die($pe->getMessage());
}

报错

1
SQLSTATE[HY000] [2002] Connection refused

解决方法

以上错误主要是对 Docker 容器的隔离机制理解不够,其实每个容器之间都是隔离的,如果有相互依赖的服务,需要进行显示的关联,比如使用选项 --link

同理,使用 docker-compose 时候,容器之间关联是采用类似如下的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# docker-compose.xml 缩减版
version: '2'
services:

...

php:
build: ./php

...

links:
- "mysql"

mysql:
build: ./mysql
ports:
- "3306:3306"
environment:
MYSQL_PASSWORD: root

注意,关键地方来了:测试连接 MySQL 的代码其实是运行在 PHP 对应的容器里,而 MySQL 服务是在它自己对应的容器里,当我们的 host 填写 127.0.0.1 时候,其实对应的是 PHP 容器里面,所以不可能找到对应的服务,从而引起上面拒绝连接的错误。

那么,怎么进行连接呢?

其实容器之间关联之后,可以通过容器名进行连接,是的,容器名!

在上面的 docker-compose.xml 文件中,MySQL 服务对应的容器名是 mysql,PHP 容器与它关联的名字也是 MySQL,所以把 127.0.0.1 改成 mysql 再进行连接即可!