Связь контейнеров по имени

Как приложение находит базу данных по имени контейнера, а не по изменчивому 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.
Проверьте себя
1. Как контейнер api обращается к контейнеру базы с именем db в одной сети?
AТолько по жёстко прописанному IP-адресу
BПо имени db, которое DNS резолвит в актуальный IP
CПо номеру порта
DПо ID контейнера
2. Почему не стоит прописывать IP-адрес контейнера в конфигурации?
AIP-адреса запрещены в Docker
BIP контейнера непостоянен и может измениться при пересоздании
CIP работает только в production
DDocker не поддерживает IP вообще
3. В какой сети работает обращение к контейнеру по имени?
AВ любой, включая стандартную bridge
BТолько в пользовательской сети, где контейнеры находятся вместе
CТолько в сети host
DТолько при отключённом DNS
Поддержать проект