为啥 PHP docker 容器无法查找 MYSQL 容器的主机名?
Posted
技术标签:
【中文标题】为啥 PHP docker 容器无法查找 MYSQL 容器的主机名?【英文标题】:Why PHP docker container can't lookup the hostname of the MYSQL container?为什么 PHP docker 容器无法查找 MYSQL 容器的主机名? 【发布时间】:2020-06-28 07:55:10 【问题描述】:我已经创建并链接了 php-apache 容器和 mysql 容器。但是,当我尝试使用 php 文件中的 PDO 建立连接时,我得到了错误。有人知道如何解决吗?谢谢。
PDO 错误:
致命错误:未捕获的 PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/html/index.php:3 Stack trace: #0 /var/www/html /index.php(3): PDO->__construct('mysql:host=mysq...', 'root', 'root') #1 main 下一个 PDOException: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo失败:名称或服务在 /var/www/html/index.php:3 中未知 堆栈跟踪:#0 /var/www/html/index.php(3): PDO->__construct('mysql:host=mysq ...', 'root', 'root') #1 main 在第 3 行的 /var/www/html/index.php 中抛出
我的目录结构:
.
├── mysql
├── php
| └── Dockerfile
├── src
| └── index.php
└── docker-compose.yml
我的 index.php 的内容:
$connection = new PDO('mysql:host=mysql-db,dbname=app', 'root', 'root');
PHP Dockerfile:
FROM php:7.3.3-apache
RUN docker-php-ext-install -j$(nproc) pdo_mysql
docker-compose.yml:
version: '3'
services:
apache-php:
build:
./php
volumes:
- ./src:/var/www/html
ports:
- "8080:80"
depends_on:
- mysql-db
links:
- mysql-db
mysql-db:
image: mysql:5.7
ports:
- "3306:3306"
volumes:
- /mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
【问题讨论】:
我认为您需要将网络添加到您的撰写文件中,例如networks: - app-network
以便在版本 3 中将它们链接在一起。
@NigelRen 结果相同。 gist
@NigelRen Docker Compose creates a default
network for you;你不需要手动声明一个。 links:
也是不必要的。
@DavidMaze,那么如果容器应该能够通过名称发现彼此,那么 OP 如何解决问题?
docker-compose 文档提到不需要“链接”。我都试过了,都没有成功。
【参考方案1】:
首先,您不需要links:
,因为这两个服务都在同一个网络中。
其次,depends_on
不会等到 MySQL 服务器启动并运行,并且 PHP 服务有可能在准备好之前开始通信,这就是您收到此错误的原因。
在这种情况下,IT 最好为您的 PHP 服务实现“等待”功能。
为此,您需要向您的 PHP 服务和代码添加一个入口点,如下所示
泊坞窗文件
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
docker-entrypoint.sh
#!/bin/sh -e
until nc -vz mysql-db:3306 > /dev/null; do
>&2 echo "mysql-db:3306 is unavailable - sleeping"
sleep 2
done
>&2 echo "mysql-db is up"
exec "YOUR COMMAND"
exit 0
【讨论】:
它以“exec 用户进程导致 mysql 容器内“没有这样的文件或目录”结束。【参考方案2】:这样做有两个问题:
1) php:apache 图像需要大量工作才能运行 php 应用程序,最好自己制作,我是从 ubuntu 18:04 图像中制作的
2) 我不记得为什么了,但是 mysql 需要设置为允许 mysql_native_passwords 才能使用(在我的情况下)php
这是我为课堂测试所做的 docker-compose 文件(因此标记为examen)以共享我的网络应用程序:
version: '3'
services:
app:
image: gnomejodas/httpd-php:examen
ports:
- 80:80
volumes:
- ./src:/var/www/html
links:
- db
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./db:/var/lib/mysql
PD。我是一个超级新手开发者(还在学习中),请放轻松。
编辑。如果您制作自己的镜像,请不要忘记CMD apachectl -D FOREGROUND
,这样您的 apache 服务就会在您运行容器时启动。
【讨论】:
【参考方案3】:毕竟,发现在我的 php 代码中,主机定义后有一个逗号,而不是分号。我很抱歉。
【讨论】:
以上是关于为啥 PHP docker 容器无法查找 MYSQL 容器的主机名?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能在我的 docker 容器中运行 phpinfo()?