Compose описывает несколько контейнеров, их сети и тома в одном YAML-файле и поднимает их одной командой. Это стандарт для локальной разработки, стендов и небольших продов на одном сервере.
Минимальный файл
# compose.yaml
services:
api:
build: .
image: registry.example.com/api:1.4.2
ports:
- "8080:8080"
environment:
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 5s
retries: 10
volumes:
pgdata:
Файл по умолчанию называется compose.yaml (старое имя docker-compose.yml тоже читается). Поле version: в начале файла устарело: Compose v2 его игнорирует и предупреждает.
Сейчас Compose это плагин Docker CLI: команда docker compose (через пробел). Отдельный docker-compose на Python это первая версия, она больше не развивается.
Сеть и имена
Compose создаёт для проекта отдельную сеть <проект>_default, и сервисы находят друг друга по имени сервиса: db, api. Имя проекта по умолчанию это имя каталога, задаётся -p или name: в файле. Порты публикуются только там, где они нужны снаружи: базе в примере порт не нужен, API ходит к ней по внутренней сети.
Основные команды
docker compose up -d # поднять в фоне (собрать, если нужно)
docker compose up -d --build # пересобрать образы
docker compose ps
docker compose logs -f api
docker compose exec db psql -U app
docker compose run --rm api npm test # разовая команда в новом контейнере
docker compose pull # скачать новые образы
docker compose down # остановить и удалить контейнеры и сеть
docker compose down -v # ...и тома: данные пропадут!
docker compose config # итоговый конфиг после подстановок
up -d идемпотентен: пересоздаёт только сервисы, у которых изменился конфиг или образ.
depends_on и готовность
depends_on: [db] задаёт только порядок запуска: api стартует после того, как контейнер db создан и запущен, но база в этот момент может ещё не принимать соединения. Чтобы ждать готовности, нужны healthcheck у зависимости и condition: service_healthy. И всё равно приложение должно уметь переподключаться: база может перезапуститься позже.
Есть ещё condition: service_completed_successfully, удобно для миграций: сервис migrate выполняется и выходит, а api ждёт его успешного завершения.
Переменные и конфигурация
${VAR}в файле подставляется из окружения shell и из файла.envрядом с compose-файлом. Подстановка происходит при разборе файла.environment:задаёт переменные контейнера,env_file:берёт их из файла.${VAR:?нужно задать VAR}прерывает запуск, если переменной нет;${VAR:-default}даёт значение по умолчанию.- Проверить итог:
docker compose config.
Не путай: .env для подстановки в compose-файл и env_file: для передачи переменных в контейнер. Это разные механизмы.
Секреты
Переменные окружения видны в docker inspect и попадают в логи при отладке. Compose умеет secrets:: файл монтируется в контейнер как /run/secrets/<имя>, многие официальные образы понимают переменные *_FILE (POSTGRES_PASSWORD_FILE).
Несколько окружений
compose.override.yamlприменяется автоматически поверх основного: удобно для разработки (bind mount кода, отладочные порты).- Явно:
docker compose -f compose.yaml -f compose.prod.yaml up -d. profiles:включают сервисы по требованию:docker compose --profile debug up.extendsи якоря YAML (x-common: &common) убирают повторы.
Ресурсы, рестарты, логи
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
restart: unless-stopped поднимет сервис после ребута и падения. Без ограничения логов json-файлы растут без конца.
Compose в проде
Для одного сервера Compose годится: просто, понятно, воспроизводимо. Чего нет: нескольких узлов, самовосстановления при падении сервера, плавного обновления без простоя из коробки, автомасштабирования. Когда это нужно, переходят на Kubernetes или другой оркестратор.
Частые ошибки
- Ждать готовности базы от простого
depends_on. docker compose down -vна проде.- Публиковать порт базы наружу «для удобства».
- Пароли прямо в
compose.yamlв репозитории. latestу образов в продовом файле.
Что спросят на собесе
- Как сервисы в compose находят друг друга.
- Что делает
depends_onи как дождаться готовности базы. - Чем
downотличается отdown -v,upотrun. - Как разделить конфигурацию для разработки и прода.
- Когда Compose перестаёт хватать и нужен Kubernetes.