Я столкнулся с интересной проблемой, в которой, кажется, есть разница между командой docker run
и использованием docker-compose
.
У меня есть два контейнера Docker, один из них - веб-сайт Apache с PHP,другой - MySQL.Я использую следующие команды для запуска контейнеров:
Веб-сайт:
docker run -p 8080:80 -d website_local
MySQL:
docker run -e MYSQL_ROOT_PASSWORD=RamaLamaDingDong --name=mysql5725 -d mysql:5.7.25
Глядя на экосистему Docker, я вижу, как они работают:
$ 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
Я установил соединение PDO с базой данных, используя имя контейнера MySQL Docker:
PHP: (USER
и PASS
верны и да,Я знаю, что не должен использовать учетные данные root)
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();
}
При попытке подключиться к базе данных я получаю следующую ошибку:
SQLSTATE [HY000] [2002] php_network_getaddresses: getaddrinfo fail: Имя или служба не известны
Если я заменим host
в строке соединений на IP-адрес Docker (172.17.0.3) контейнера, который он правильно подключит.
Теперь это становится интересным.Если я поднимаю контейнеры с помощью 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"
Функция PHP подключается правильно, используя имя контейнера Docker (mysql5725
), но не может подключиться с использованием IP-адреса контейнера Docker.
Часто в тестовой среде я хочу останавливать и перестраивать только определенные контейнеры, особенно когда имеешь дело с более чем двумя образами Docker.Я должен использовать имя ресурса только при установлении соединения, потому что нет гарантии, что сеть будет каждый раз назначать контейнеры одни и те же IP-адреса.
Почему эти два метода запуска контейнеров Docker дают разные результаты?Есть ли способ «нормализовать» это, поэтому подключение по имени будет работать независимо от того, как запущен контейнер?