Docker Compose превращает управление многоконтейнерными приложениями из головной боли в элегантный танец. Но без грамотной настройки сети этот танец напоминает попытку синхронного плавания в бассейне, где каждый плывёт в своём направлении. Понимание сетевых возможностей Compose — это ключ к созданию отказоустойчивых, безопасных и эффективных микросервисных архитектур, где контейнеры общаются чётко и предсказуемо.
Сети по умолчанию: Магия, которая происходит сама собой
Когда вы запускаете docker-compose up, Compose автоматически создаёт для вашего проекта выделенную сеть типа bridge. Это ваша приватная песочница. Все сервисы, описанные в файле docker-compose.yml, подключаются к этой сети и могут находить друг друга по имени сервиса. Это базовый, но мощный механизм service discovery.
Имя сети по умолчанию формируется на основе имени проекта (указанного в .env файле или через флаг -p) и суффикса _default. Например, myapp_default.
Явное определение сетей: Полный контроль
Для сложных сценариев вы можете и должны определять сети явно. Это открывает мир возможностей.
Создание пользовательских bridge-сетей
В корне файла docker-compose.yml вы можете секцию networks:
networks:
backend:
driver: bridge
ipam:
config:
- subnet: \"172.28.0.0/16\"
frontend:
driver: bridge
А затем в каждом сервисе указать, к каким сетям он подключен:
services:
database:
image: postgres
networks:
- backend
api:
build: ./api
networks:
- backend
- frontend
web:
build: ./web
networks:
- frontend
Теперь API-сервис выступает в роли моста между внутренней сетью backend (где живёт база данных) и внешней frontend (откуда идут запросы от веб-приложения). База данных изолирована от прямого доступа извне.
Критически важные параметры сети
- aliases: Псевдонимы для сервиса в сети. Дополнительные DNS-имена.
- ipv4_address / ipv6_address: Фиксация статического IP-адреса для контейнера в сети с ручной настройкой IPAM.
- driver_opts: Опции драйвера сети. Например, для настройки MTU.
- external: true: Подключение к сети, созданной вне Docker Compose (например, через
docker network create).
Используйте external сети для подключения контейнеров из разных проектов Compose. Это основа для взаимодействия независимо развёрнутых микросервисов.
Публикация портов: Мост между мирами
Ключ ports в конфигурации сервиса создаёт проброс портов с хоста в контейнер. Синтаксис \"HOST:CONTAINER\".
services:
nginx:
image: nginx
ports:
- \"80:80\" # Порт 80 хоста -> порт 80 контейнера
- \"127.0.0.1:443:443\" # Только локальный доступ на хосте
Для временной публикации портов только для других сервисов в той же сети используйте expose. Эти порты не публикуются на хост-машину.
Практический пример: Трёхзвенная архитектура
Рассмотрим типичный стек: Nginx + Python-приложение + PostgreSQL.
version: '3.8'
networks:
public:
private:
services:
nginx:
image: nginx:alpine
ports:
- \"80:80\"
networks:
- public
depends_on:
- app
app:
build: ./app
networks:
public:
private:
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
networks:
- private
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Nginx общается с приложением через сеть public. Приложение общается с базой данных через изолированную сеть private. База данных не имеет выхода в публичную сеть.
Диагностика и утилиты
docker network ls— список всех сетей.docker network inspect [NETWORK_NAME]— детальная информация о сети, включая подключённые контейнеры и IP-адреса.docker-compose exec [SERVICE] ping [ANOTHER_SERVICE]— проверка связности между сервисами.
FAQ: Часто задаваемые вопросы
Как контейнеры находят друг друга по имени?
Docker Compose встраивает в создаваемые сети встроенный DNS-сервер. Когда контейнер пытается разрешить имя сервиса (например, db), DNS возвращает внутренний IP-адрес этого контейнера в данной сети.
Можно ли подключить существующий контейнер к сети Compose?
Да, если сеть определена как external. Используйте команду docker network connect [NETWORK_NAME] [CONTAINER_NAME].
В чём разница между ports и expose?
ports публикует порты на хост-машину, делая сервис доступным извне. expose только документирует, какие порты использует сервис, и открывает их для других контейнеров в той же сети, но не публикует на хост.
Как настроить статический IP для контейнера?
Необходимо явно определить сеть с настройками IPAM (IP Address Management) и затем указать ipv4_address в конфигурации сервиса внутри этой сети.
Что такое сеть host и когда её использовать?
При использовании сети host контейнер делит сетевое пространство с хост-машиной (не имеет собственной сетевой изоляции). Это может дать выигрыш в производительности, но является менее безопасным. Используйте осторожно, в основном для высокопроизводительных сетевых приложений (например, балансировщиков нагрузки).