为啥 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()?

无法连接在 docker 容器上运行的 mysql 服务器

docker bookstack 迁移

无法更新 Docker 容器中的 php.ini 文件

debian9 安装docker 以及在docker中 安装centos 6 安装指定版本的PHP和MySQ

php mcrypt 在 docker 容器上启用后无法正常工作