【发布时间】:2019-04-12 11:47:52
【问题描述】:
我遇到了一个有趣的问题,docker run 命令和使用docker-compose 之间似乎存在差异。
我有两个 Docker 容器,一个是带有 PHP 的 Apache 网站,另一个是 MySQL。我使用以下命令来运行容器:
网站:
docker run -p 8080:80 -d website_local
MySQL:
docker run -e MYSQL_ROOT_PASSWORD=RamaLamaDingDong --name=mysql5725 -d mysql:5.7.25
查看 Docker 生态系统,我可以看到它们都在运行:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
849c421e750b website_local "/usr/sbin/apache2ct…" 19 minutes ago Up 19 minutes 0.0.0.0:8080->80/tcp pedantic_tesla
ccebba95693b mysql:5.7.25 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes 3306/tcp, 33060/tcp mysql5725
我已经使用 MySQL Docker 容器的名称设置了到数据库的 PDO 连接:
PHP:(USER 和 PASS 是正确的,是的,我知道我不应该使用 root 的凭据)
try {
$dbh = new PDO('mysql:host=mysql5725;dbname=grocery;charset=utf8', USER, PASS);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo $e->getMessage();
$errorCode = $e->getCode();
}
尝试连接数据库时出现以下错误:
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known
如果我将连接字符串中的 host 替换为容器的 Docker IP 地址 (172.17.0.3),它将正确连接。
现在变得有趣了。如果我使用 Docker Compose 调出容器:
version: '3'
services:
db:
image: mysql:5.7.25
container_name: mysql5725
environment:
MYSQL_ROOT_PASSWORD: RamaLamaDingDong
ports:
- "3306:3306"
web:
image: website_local:latest
container_name: website_local
depends_on:
- db
volumes:
- ./website/www:/var/www/html/
ports:
- "8080:80"
PHP 函数使用 Docker 容器的名称 (mysql5725) 正确连接,但无法使用 Docker 容器的 IP 地址连接。
在测试环境中很多时候我只想停止并重建某些容器,尤其是在处理两个以上的 Docker 镜像时。我应该只在建立连接时使用资源的名称,因为无法保证网络每次都会为容器分配相同的 IP 地址。
为什么这两种启动 Docker 容器的方法会产生不同的结果?有没有办法“规范化”这个,所以无论容器如何启动,按名称连接都可以工作?
【问题讨论】:
标签: php docker docker-compose