duanjian4698 2019-04-12 11:47
浏览 694
已采纳

Docker,PHP PDO和单个MySQL容器(无法通过容器名称连接)

I've run into an interesting issue where there seems to be a difference between the docker run command and using docker-compose.

I have two Docker containers, one is an Apache website with PHP, the other a MySQL. I use the following commands to run the containers:

Website:

docker run -p 8080:80 -d website_local

MySQL:

docker run -e MYSQL_ROOT_PASSWORD=RamaLamaDingDong --name=mysql5725 -d mysql:5.7.25

Looking at the Docker ecosystem I can see them both running:

$ 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

I have setup a PDO connection to the database, using the name for the MySQL Docker container:

PHP: (the USER and PASS are correct and yes, I know I shouldn't use the root's credentials)

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();
    }

When attempting to connect to the database I get the following error:

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

If I replace host in the connections string with the Docker IP address (172.17.0.3) of the container it connects properly.

Now it gets interesting. If I bring up the containers using 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"

The PHP function connects correctly using the name of the Docker container (mysql5725), but cannot connect using the IP address of the Docker container.

Many times in a testing environment I only want to stop and rebuild certain containers, especially when dealing with more than two Docker images. I should only have to use the resource's name when making a connection because there is no guarantee the network will assign the same IP addresses to containers every time.

Why should these two methods of launching Docker containers produce different results? Is there a way to 'normalize' this, so connecting by name will work no matter how the container is launched?

  • 写回答

1条回答 默认 最新

  • doudongdang4483 2019-04-12 12:33
    关注

    Docker Compose automatically sets up a network for you:

    By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

    The default bridge network that Docker creates on its own doesn't provide DNS so you can't use it to connect to containers using their names. You'll probably want to set up a network yourself, e.g. with

    docker network create mynetwork
    

    and then connect your containers to it, e.g. with

    docker network connect mynetwork mysql5725
    docker network connect mynetwork php-container
    

    Note that this isn't the only difference between Docker Compose and manually running containers.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 有赏,i卡绘世画不出
  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码