简体   繁体   中英

Why PHP docker container can't lookup the hostname of the MYSQL container?

I have created and linked php-apache container with MYSQL container. But when I try to establish connection using PDO from a php file I got the error. Does anybody know how it could be fixed ? Thanks.

PDO error:

Fatal error: Uncaught 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} Next PDOException: SQLSTATE[HY000] [2002] 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} thrown in /var/www/html/index.php on line 3

My directory structure:

.
├── mysql
├── php
|   └── Dockerfile
├── src
|   └── index.php
└── docker-compose.yml

Content of my 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

First, you don't need the links: that will be done automatically since both services are in the same network.

Second, depends_on will not wait until the MySQL server is up and running and there is a chance the PHP service starts communicating before it is ready and that is why you receive this error.

In such cases, IT is better to implement a "wait for" functionality for your PHP service.

for that, you need to add an entry point to your PHP service and code like this

docker file

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

I had 2 issues doing this:

1) php:apache images need a lot of work to run php applications, it's better to just make your own, I did mine from ubuntu 18:04 image

2) I don't recall why, but mysql needs to be set to allow mysql_native_passwords in order to work with (in my case) php

Here's the docker-compose file I did for an test in class (thus the tag called examen)to share my web app:

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. I'm a super newbie developer (still studying), please go easy on me.

EDIT. If you make your own image, dont forget CMD apachectl -D FOREGROUND so your apache service starts when you run the container.

After all, find out that in my php code I have a comma after host definition, instead of semicolon. My apologizes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM