PHP can not resolve mysql container name under cer

2019-01-29 08:39发布

问题:

I have legacy PHP application. It used mysqli to make mysql things. So in config I have DSN string to connect to mysql service. Like that

mysql://username:password@db_hostname/dbname

Mysqli returns error

Warning: mysqli::real_connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known

But if I will try connect by hand using this

mysqli::real_connect("db_hostname")

It says Warning: mysqli::real_connect(): (HY000/1045): Access denied for user ''@'172.21.0.3' (using password: NO)

real_connect("user@db_hostname"), real_connect("mysql:db_hostname"), real_connect("mysql:host=db_hostname") can not resolve host address.

What I'm doing wrong?

docker-compose.yml:

version: "3"
services:
  nginx:
    image: nginx:1.13-alpine
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./docker/nginx/errors.log:/var/logs/errors.log
      - ./docker/nginx/access.log:/var/logs/access.log
      - ./:/var/www/html
    ports:
      - "8081:80"
    command: nginx -g "daemon off;"
  php:
    build:
      context: ./docker/
      dockerfile: php.Dockerfile
    user: "1000"
    volumes:
      - ./docker/timezone.php.ini:/usr/local/etc/php/conf.d/timezone.php.ini:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - ./:/var/www/html

  db_hostname:
    image: mysql:5.5
    user: "1000"
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_USER=user
      - MYSQL_PASSWORD=user
    volumes:
      - ./docker/mysql:/var/lib/mysql
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

回答1:

As you missing linking you db container with php. When you link db with PHP it will be accessible from localhost of PHP.

Here is I modified your docker-compose file as I like alpine everywhere ;). And I use adminer and link with db to verfiy connection instead of code level checking. As i dont have you php docker file so i am creating php:alpine which contain php7.

version: "3"
services:
  nginx:
    image: nginx:1.13-alpine
    container_name: nginx
    ports:
      - "8081:80"
    command: nginx -g "daemon off;"
  db:
    image: mysql:5.5
    environment:
      MYSQL_ROOT_PASSWORD: example

  php:
    image: php:alpine
    container_name: php
    tty: true
    links:
     - db 
  adminer:
    image: adminer
    container_name: adminer
    ports:
      - 8080:8080
    links:
     - db 

Then i installed mysqli in php container

docker exec -it php ash

and run below command

docker-php-ext-install mysqli;

Then create test.php

here server name is db. Note that your server name will be what is db container name which is link to php. if you ping db in php container it will ping db container.

    <?php
$servername = "db";
$username = "root";
$password = "example";

// Create connection
$conn = new mysqli($servername, $username, $password);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 
echo "Connected successfully";
?>

Now run this file in php container. You can mount and run your php code but this is what I did for testing. And I tried as a root user.

php -f test.php

And here is adminer which also link with db