Связь контейнеров по имени
Как приложение находит базу данных по имени контейнера, а не по изменчивому IP-адресу.
Service discovery по имени — встроенный DNS Docker, который резолвит имя контейнера в его текущий IP внутри пользовательской сети.
Проблема жёстких IP-адресов
У каждого контейнера есть IP, но он не постоянный: пересоздали контейнер — адрес мог измениться. Зашивать IP в конфигурацию приложения нельзя. Решение — обращаться по имени.
DNS по имени контейнера
В пользовательской сети Docker поднимает встроенный DNS: имя контейнера становится его сетевым адресом. Контейнер с --name db доступен другим контейнерам той же сети как хост db.
# Создаём сеть
docker network create app-net
# База данных с именем db
docker run -d --name db --network app-net \
-e POSTGRES_PASSWORD=secret postgres:16
# Приложение в той же сети
docker run -d --name api --network app-net \
-p 8000:8000 my-app:1.0
Теперь внутри контейнера api строка подключения к базе указывает host=db, а не IP:
postgresql://postgres:secret@db:5432/postgres
Имя db автоматически резолвится в актуальный IP базы. Пересоздадите контейнер базы — приложение продолжит находить её по тому же имени.
Проверим резолвинг изнутри
Зайдём в контейнер api и пропингуем базу по имени:
docker exec -it api ping db
Вывод:
PING db (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.089 ms
Имя db разрешилось в IP 172.18.0.2 — связь по имени работает.
Важное условие
DNS по имени работает только в пользовательской сети (созданной через docker network create). Контейнеры должны быть в одной сети. Именно этот механизм лежит в основе Docker Compose, который вы освоите в следующем разделе.
Итог
- IP контейнеров непостоянны, поэтому обращаются по имени, а не по адресу.
- В пользовательской сети имя контейнера резолвится встроенным DNS в его IP.
- В строке подключения хостом служит имя контейнера, например
db.