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?