Ответ
В Docker Compose контейнеры (сервисы) взаимодействуют друг с другом через внутреннюю виртуальную сеть, которую Compose создает автоматически для проекта.
Ключевой механизм — встроенный DNS-сервер. Каждый сервис получает DNS-имя, совпадающее с его названием в docker-compose.yml. Это позволяет обращаться к одному контейнеру из другого по имени, как к обычному хосту в сети.
Пример docker-compose.yml:
version: '3.8'
services:
api:
build: ./api
# Порт 8000 доступен только внутри сети Docker
expose:
- "8000"
frontend:
build: ./frontend
# Пробрасываем порт 80 контейнера на порт 8080 хоста
ports:
- "8080:80"
В этом примере:
- Сервис
frontendможет отправить запрос к сервисуapiпо адресуhttp://api:8000. - Docker Compose автоматически разрешит имя
apiво внутренний IP-адрес соответствующего контейнера. - Пользователь может получить доступ к
frontendчерезhttp://localhost:8080, но не может напрямую обратиться кapiизвне, так как его порт не проброшен с помощьюports.
Ответ 18+ 🔞
А, ну это же про ту самую магию, когда твои контейнеры начинают друг друга находить, будто у них встроенный радар! Смотри, как это работает, а то некоторые думают, там кабели эфирные тянуть надо.
Понимаешь, Docker Compose — он не просто так, он хитрая жопа. Когда ты его запускаешь, он берёт и создаёт для всего этого балагана свою собственную, закрытую сетку. Как будто детский сад с забором. Внутри этой сетки у каждого сервиса-контейнера появляется своё DNS-имя, прямо как кличка.
И главный фокус в том, что имя это — ровно то, которое ты написал в docker-compose.yml. Хочешь к api обратиться? Пиши http://api:8000 из другого контейнера, и всё, хуй с горы — запрос улетит куда надо. Внутренний DNS-сервер, который Compose поднимает, сам всё разберёт, какой контейнер за каким IP сидит.
Вот смотри на этот пример, тут всё как на ладони:
version: '3.8'
services:
api:
build: ./api
# Порт 8000 доступен только внутри сети Docker
expose:
- "8000"
frontend:
build: ./frontend
# Пробрасываем порт 80 контейнера на порт 8080 хоста
ports:
- "8080:80"
Что здесь происходит, ёпта? Сервис frontend может спокойно стучаться к api по адресу http://api:8000. Это как если бы они в одной комнате стояли и один другому крикнул: «Эй, API, дай сюда данные!».
А вот для внешнего мира, для нас с тобой, порт 8000 у api — невидимка, потому что он только expose, а не ports. Это как внутренняя линия, для своих. Зато frontend выставил свою рожу наружу через ports: - "8080:80". Так что мы, пользователи, лезем на http://localhost:8080, а он уже внутри сам разбирается с api.
Короче, вся фишка в том, что Compose сам настраивает эту паутину связей. Тебе только имена правильно прописать, а он уже под капотом ебушки-воробушки наколдует, чтобы они друг друга видели. Удобно же, а?