Перейти к основному содержимому

Docker Compose

Разработчику Архитектору Инженеру

Docker Compose

Docker Compose — инструмент для запуска многоконтейнерных приложений в Docker. Конфигурацию приложения (сервисы, сети, тома, переменные окружения) он собирает в один YAML-файл.

Используйте docker compose (плагин Compose V2; бинарник docker-compose V1 устарел). Основные команды — в блоках ниже.

docker compose

Разбор:

  • Вызов плагина Compose V2 как подкоманды docker (не отдельный бинарник docker-compose v1).
  • Без аргументов выводит справку по подкомандам — up, down, ps, logs, exec, build и др.
  • Рабочий каталог должен содержать compose.yaml, compose.yml или docker-compose.yml.
  • Имя проекта по умолчанию — имя родительской папки; переопределяется -p или переменной COMPOSE_PROJECT_NAME.
  • Несколько файлов объединяют флагом -f; переменные подставляются из .env в каталоге проекта.

Docker Compose читает файл compose.yaml (или docker-compose.yml), применяет описанную конфигурацию и поднимает сервисы как единый проект. Он автоматически объединяет контейнеры в сеть, подключает тома и управляет жизненным циклом через единый набор команд.

Главная польза Compose — повторяемый запуск сложной системы без десятков ручных docker run. Одна команда поднимает сразу весь стек, и команда получает одинаковую среду на любой машине с Docker Engine.

Play ITЗагрузка интерактивного демо…

Готовые compose.yaml для nginx, PostgreSQL, Redis, WordPress, мониторинга и dev-окружения — с разбором ключей — Docker Compose — готовые стеки. PromQL для стека Prometheus + Grafana — галерея запросов. Отдельные фрагменты nginx.conf (proxy, SPA, PHP-FPM, TLS) — Nginx — конфиги под задачу.

Файл Compose хранится рядом с кодом в Git. Поэтому любой участник команды может взять репозиторий и воспроизвести окружение локально, а DevOps-инженеры — использовать те же описания для тестовых стендов и серверных сред.

Файл конфигурации определяет три основных уровня абстракции:

  • Сервисы — описание каждого контейнера, образа, портов и зависимостей;
  • Сети — логическая изоляция и связь между контейнерами;
  • Тома — управление постоянными данными и их хранение вне контейнеров.

Компонент поддерживает функции масштабирования количества экземпляров сервиса, перезапуска упавших процессов и автоматического обновления образов при наличии новых версий.


Когда Compose особенно полезен

Compose быстро закрывает типовые задачи команды разработки и тестирования:

  • локальный запуск "как в проде", где сервисы уже разделены на app, db, cache;
  • воспроизводимые стенды для ручного QA и интеграционных тестов;
  • запуск служебных задач в окружении проекта, например миграций и сидирования;
  • стандартизированные команды для всей команды через docker compose up/down/logs.

Compose экономит время на ручной оркестрации нескольких docker run и снижает число ошибок в конфигурации.


Архитектура работы инструмента

Работа Docker Compose базируется на парсинге декларативного файла конфигурации. Пользователь описывает желаемое состояние системы, а утилита приводит реальное состояние хоста к этому описанию. Процесс запуска включает несколько последовательных этапов.

Первым шагом происходит чтение файла compose.yaml (или docker-compose.yml). Утилита проверяет синтаксис документа и структуру данных. Формат YAML требует строгого соблюдения отступов, так как они определяют иерархию элементов. Любая ошибка в отступах приведет к невозможности запуска.

После валидации конфигурации система анализирует зависимости между сервисами. Если один сервис зависит от другого, например, база данных должна быть доступна перед запуском веб-приложения, Compose учитывает эти связи. Однако прямая зависимость по времени старта не гарантирует мгновенную готовность базы данных. Для решения этой проблемы используются механизмы ожидания или специальные скрипты внутри контейнеров.

Далее утилита создает необходимые сетевые интерфейсы. По умолчанию каждый проект (категория папок с файлом compose) получает собственную виртуальную сеть. Контейнеры подключаются к этой сети автоматически, если не указано иное. Внутри этой сети сервисы могут обращаться друг к другу по именам сервисов, определенным в файле конфигурации.

Следующим этапом идет создание томов. Тонкие слои хранения данных создаются либо системой управления Docker, либо пользовательскими драйверами. Тома сохраняют данные даже после удаления контейнеров. Это критически важно для баз данных и других систем, требующих сохранения состояния.

Затем начинается процесс запуска контейнеров. Команда docker compose up инициирует сборку образов, если они отсутствуют локально, и затем создаёт контейнеры согласно описанию. Каждый контейнер получает уникальный идентификатор и имя, основанное на имени сервиса и номера экземпляра.

docker compose up

Разбор:

  • Создаёт сети и тома по описанию, при необходимости собирает (build) или скачивает (pull) образы.
  • Запускает контейнеры в порядке с учётом depends_on и профилей (--profile).
  • Подключает сервисы к project-default bridge-сети с внутренним DNS по имени сервиса.
  • Логи всех сервисов в foreground-режиме идут в один терминал до остановки.
  • Флаги -d, --build, --force-recreate, --no-deps меняют режим старта без смены подкоманды.

Управление ресурсами осуществляется через ограничения CPU и памяти, которые можно задать в конфигурации. Система распределяет доступные ресурсы хоста между активными контейнерами. При исчерпании ресурсов операционная система может ограничить работу процесса.

Завершение работы также управляется централизованно. Команда docker compose down останавливает все контейнеры проекта, удаляет созданные сети и тома (опционально). Это позволяет быстро очистить среду тестирования без ручного вмешательства.

docker compose down

Разбор:

  • Останавливает контейнеры всех сервисов проекта и удаляет созданные compose сети.
  • Named volumes по умолчанию сохраняются — повторный up поднимет БД с прежними данными.
  • Не удаляет образы; освобождает имена контейнеров для следующего up.
  • --volumes при необходимости сбрасывает dev-данные между итерациями тестирования.
  • --remove-orphans убирает контейнеры сервисов, удалённых из YAML.

Структура файла конфигурации

Файл конфигурации представляет собой набор ключей и значений, организованных в иерархическую структуру. Корневой элемент содержит раздел services, который является обязательным. В нем перечисляются все компоненты приложения.

Каждый сервис определяется своим именем и набором параметров. Параметры задают поведение контейнера и его взаимодействие с внешней средой. Основные параметры включают образ, команду запуска, переменные окружения и правила проброса портов.

Пример структуры файла:

Код ITЗагрузка примера кода…

Разбор:

  • Ключ version: '3.8' исторически указывал схему файла; в Compose V2 часто опускают — валидатор ориентируется на Compose Specification.
  • services.web с image: nginx:alpine тянет лёгкий образ из registry; тег alpine фиксирует базовую ОС.
  • ports: "80:80" — форма хост:контейнер; на localhost:80 откроется nginx внутри контейнера.
  • Bind ./html:/usr/share/nginx/html подставляет статику с диска разработчика без пересборки образа.
  • environment у db задаёт суперпользователя Postgres; в проде пароли выносят в secrets или .env.
  • Именованный том pgdata в корне файла объявляет persistent storage для данных СУБД.

Параметр image указывает на используемый образ. Значение может содержать имя образа и тег версии. Если тег не указан, система использует тег latest. Образ загружается из реестра Docker Hub или локального хранилища.

Параметр ports определяет правила трансляции портов. Формат записи host_port:container_port означает, что запросы, пришедшие на порт хоста, будут перенаправлены в контейнер. Использование протоколов TCP и UDP возможно через указание суффикса.

Параметр environment задает переменные окружения внутри контейнера. Эти переменные доступны приложению во время выполнения. Они позволяют изменять поведение программы без пересборки образа. Значения могут быть строками, числами или булевыми значениями.

Параметр volumes связывает файловые пути хоста с директориями внутри контейнера. Синтаксис host_path:container_path определяет точку монтирования. Типы путей могут быть абсолютными путями на хосте или именами томов, определенных в секции volumes.

Секция networks позволяет создавать пользовательские сети. Это дает возможность изолировать часть сервисов от остальной системы или создать сложную топологию взаимодействия. Сети могут иметь разные драйверы, такие как bridge, host или overlay.

Секция depends_on объявляет зависимости между сервисами. При docker compose up зависимые сервисы запускаются первыми. Важно помнить, что наличие зависимости не означает ожидание полной готовности сервиса. Приложение должно самостоятельно проверять доступность зависимых компонентов.

docker compose up

Разбор:

  • Читает compose.yaml / docker-compose.yml и поднимает все описанные сервисы как единый проект.
  • Учитывает depends_on — зависимые сервисы стартуют раньше по порядку создания.
  • Создаёт default-сеть проекта и подключает контейнеры для DNS по имени сервиса.
  • Без -d процесс CLI остаётся привязанным к логам; остановка Ctrl+C по умолчанию останавливает контейнеры.
  • Изменения только в bind-mount исходников не требуют up, если контейнер уже запущен с тем же mount.

Секция restart определяет политику перезапуска контейнера. Возможные значения — no, always, on-failure, unless-stopped. Политика always гарантирует, что контейнер будет запущен сразу после остановки или сбоя системы.


Минимальный шаблон для старта проекта

Ниже компактный каркас, с которого удобно стартовать большинство веб-проектов:

Код ITЗагрузка примера кода…

Разбор:

  • Секция services без устаревшего version: соответствует Compose Specification (V2 plugin).
  • build: . собирает образ приложения из Dockerfile в каталоге compose-файла.
  • ports: "3000:3000" публикует порт приложения на хост для локальной разработки.
  • depends_on: - db задаёт порядок создания контейнеров, но не ждёт готовности PostgreSQL к подключениям.
  • image: postgres:16 фиксирует мажорную версию СУБД; пароль через POSTGRES_PASSWORD обязателен для первого запуска.
  • Том pg_data монтируется в /var/lib/postgresql/data — данные переживают docker compose down без -v.

Дальше конфигурацию расширяют healthcheck, профилями, секретами и ограничениями ресурсов.


Управление жизненным циклом

Утилита предоставляет набор команд для управления состоянием системы. Ниже — основные команды с примерами.

docker compose up — запуск приложения. Флаг -d переводит процессы в фоновый режим (detached mode), позволяя продолжать работу в терминале. Без -d вывод логов всех сервисов отображается в консоли в реальном времени. Параметр --build пересобирает образы перед запуском, игнорируя кэш.

docker compose up
docker compose up -d
docker compose up -d --build

Разбор:

  • up без флагов поднимает стек в foreground и мультиплексирует логи в один терминал.
  • -d (detached) возвращает управление shell сразу после старта контейнеров.
  • --build принудительно пересобирает образы с build: перед созданием контейнеров.
  • При отсутствии локального образа для image: выполняется pull, если не отключено политикой.
  • Повторный up пересоздаёт контейнеры при изменении конфигурации, влияющей на create (образ, env, mounts).

docker compose down — остановка и удаление контейнеров, сетей и томов текущего проекта. Параметр --volumes дополнительно удаляет тома с данными. Это действие необратимо и приводит к потере сохранённых данных.

docker compose down
docker compose down --volumes

Разбор:

  • down останавливает и удаляет контейнеры и сети, созданные для проекта.
  • --volumes удаляет named volumes, перечисленные в top-level volumes: — данные БД будут потеряны.
  • Bind-монты с хоста не удаляются; очищается только docker-managed storage.
  • Флаг --remove-orphans убирает контейнеры сервисов, убранных из compose-файла.
  • Образы остаются на диске, пока явно не указан --rmi.

docker compose ps — список активных контейнеров проекта — имя, статус, порты и число экземпляров.

docker compose ps

Разбор:

  • Таблица контейнеров текущего compose-проекта — NAME, IMAGE, COMMAND, SERVICE, CREATED, STATUS, PORTS.
  • Показывает только контейнеры, созданные этим проектом (префикс имени из каталога или -p).
  • Порты в колонке PORTS — проброс 0.0.0.0:host->container для опубликованных сервисов.
  • Для остановленных контейнеров добавляют docker compose ps -a.
  • Не заменяет docker ps по всему хосту — только scope проекта.

docker compose logs — вывод логов одного или всех сервисов. Флаг -f следит за логами в реальном времени (аналог tail -f). Параметр --tail N показывает только последние N строк.

docker compose logs
docker compose logs -f web
docker compose logs --tail 50

Разбор:

  • Без аргументов — логи всех сервисов проекта с префиксом имени сервиса в строке.
  • -f (follow) держит поток открытым, как tail -f, до прерывания Ctrl+C.
  • --tail 50 ограничивает начальный вывод последними 50 строками на сервис.
  • --since 10m и --until фильтруют по времени (в поддерживаемых версиях CLI).
  • Логи берутся из драйвера logging контейнера (по умолчанию json-file на локальном Engine).

docker compose exec — выполнение команды внутри работающего контейнера (аналог docker exec).

docker compose exec web sh
docker compose exec db psql -U admin

Разбор:

  • Первый пример открывает интерактивную оболочку в работающем контейнере web (часто с -it).
  • Второй запускает psql в контейнере db с пользователем admin — имя должно совпадать с POSTGRES_USER.
  • Имя сервиса (web, db) — как в секции services:, не полное имя контейнера.
  • Команда выполняется в default network namespace контейнера — доступны те же DNS-имена, что у основного процесса.
  • Для неинтерактивных скриптов флаги -T отключают TTY.

docker compose stop / start — временная остановка и повторный запуск контейнеров без удаления ресурсов.

docker compose stop
docker compose start

Разбор:

  • stop отправляет SIGTERM контейнерам и ждёт grace period (stop_grace_period в compose), затем SIGKILL.
  • Контейнеры и тома остаются — быстрый перезапуск без пересоздания через start.
  • start поднимает ранее остановленные контейнеры с прежними ID и томами.
  • Не перечитывает изменения compose-файла; после правки конфигурации нужен up --force-recreate.
  • Отличается от down, который удаляет контейнеры и сети проекта.

docker compose kill — принудительное завершение контейнеров (сигнал SIGKILL), когда обычная остановка не срабатывает.

docker compose kill

Разбор:

  • Отправляет сигнал завершения (по умолчанию SIGKILL) всем контейнерам проекта.
  • Контейнеры не удаляются — остаются в статусе exited, в отличие от down.
  • Опционально docker compose kill -s SIGTERM web для мягкой остановки одного сервиса.
  • Используют, когда stop не срабатывает из-за зависшего процесса или игнорирования SIGTERM.
  • Named volumes и сети проекта сохраняются.

docker compose config — проверка синтаксиса файла конфигурации и вывод нормализованного варианта.

docker compose config

Разбор:

  • Проверяет compose-файл и выводит объединённую конфигурацию после merge нескольких -f файлов.
  • Подставляет переменные из .env — удобно увидеть итоговые значения environment перед деплоем.
  • Не изменяет состояние Docker на хосте.
  • В скриптах CI часто комбинируют с docker compose config --quiet для проверки без вывода.
  • Ошибки в отступах YAML или неверных ключах видны до долгой сборки образов.

docker compose build — сборка образов для сервисов. Параметр --parallel ускоряет сборку нескольких образов одновременно.

docker compose build
docker compose build --parallel

Разбор:

  • build читает контекст и Dockerfile из полей build: каждого сервиса.
  • Без флагов сервисы собираются последовательно; --parallel ускоряет независимые сборки на многоядерном хосте.
  • Аргументы сборки передают через build.args в compose или --build-arg в CLI.
  • Результат — локальный образ с именем проект-сервис; публикация в registry — отдельным docker push.
  • --pull при сборке обновляет базовый образ FROM перед docker build.

docker compose pull — загрузка образов из реестра без создания контейнеров.

docker compose pull

Разбор:

  • Загружает из registry образы, указанные в image: для всех сервисов проекта.
  • Не создаёт и не запускает контейнеры — только обновляет локальный кэш образов.
  • Полезно перед up на CI-агенте или при фиксированных тегах для воспроизводимости сборки.
  • Сервисы только с build: без image: не затрагиваются; для них нужен docker compose build.
  • При недоступном registry команда завершится с ошибкой для проблемного образа.

docker compose pause / unpause — заморозка и возобновление выполнения всех контейнеров проекта.

docker compose pause
docker compose unpause

Разбор:

  • pause замораживает все процессы контейнеров проекта через cgroup freezer — CPU не потребляется.
  • Состояние памяти и файловых дескрипторов сохраняется до unpause.
  • Сетевые сокеты могут "зависнуть" с точки зрения клиентов — для продакшена чаще используют stop/start.
  • unpause возобновляет выполнение с того же места, без пересоздания контейнеров.
  • Команды действуют на весь проект; выборочная пауза одного сервиса — через docker pause <container>.

Работа с сетью и связностью

Встроенная сеть Docker Compose обеспечивает автоматическое подключение всех сервисов проекта к общему мосту. Сервисы получают возможность общаться друг с другом по именам, указанным в конфигурации.

Механизм DNS встроен в сетевой стек Docker. Каждому контейнеру присваивается имя, равное имени сервиса. Веб-сервис может обратиться к базе данных по адресу db вместо IP-адреса. Это упрощает конфигурацию приложений и делает их независимыми от динамических адресов.

Для создания изолированных сетей используется секция networks. Можно определить несколько сетей с разными настройками безопасности и доступности. Сервисы подключаются к нужным сетям через параметр networks внутри определения сервиса.

Драйверы сетей определяют способ взаимодействия. Драйвер bridge создает изолированную сеть для проекта. Драйвер host позволяет контейнерам использовать сетевой стек хоста напрямую. Драйвер overlay используется в кластерах Swarm для связи контейнеров на разных узлах.

Правила проброса портов (ports) делают сервисы доступными извне. Порт хоста мапится на порт контейнера. Внешние клиенты обращаются к публичному порту, а Docker перенаправляет трафик внутрь контейнера.

Параметр expose открывает порт только для внутренних сервисов проекта. Этот порт не доступен извне хоста, но доступен другим контейнерам в той же сети. Это повышает безопасность, скрывая внутренние сервисы от прямого доступа.

Настройка links устарела и не рекомендуется к использованию. Она была заменена встроенной системой DNS и автоматической сетью. Использование ссылок усложняет конфигурацию и снижает производительность.

Конфигурация прокси-серверов возможна через параметры http_proxy и https_proxy в переменной окружения. Это позволяет контейнерам выходить в интернет через корпоративный шлюз.


Управление данными и томами

Сохранение данных в контейнерах требует использования томов. Данные внутри контейнера исчезают при его удалении. Тома хранят файлы на диске хоста или в управляемом хранилище.

Секция volumes в корне файла определяет имена томов. Эти тома создаются автоматически при первом использовании. Docker управляет их расположением и правами доступа.

Типы томов:

  • Bind mounts — привязка конкретной директории хоста к контейнеру. Используется путь вида /path/on/host:/path/in/container. Подходит для разработки, когда нужно видеть изменения кода в реальном времени.
  • Named volumes — тома с уникальным именем. Используются для хранения данных баз данных, логи и других важных файлов. Данные сохраняются независимо от жизненного цикла контейнера.
  • Tmpfs mounts — временные тома, хранящиеся в оперативной памяти хоста. Не подходят для больших объемов данных, но обеспечивают высокую скорость.

Права доступа к томам регулируются параметром user в сервисе. Контейнер может запускаться под определенным пользователем или группой. Это предотвращает проблемы с правами чтения/записи файлов.

Шифрование данных в томах возможно через внешние драйверы или настройки Docker Security. Стандартные тома не шифруются автоматически.

Резервная копия named volume (пример с busybox и tar):

docker run --rm \
-v my_volume:/data \
-v $(pwd):/backup \
busybox tar cvf /backup/backup.tar /data

Разбор:

  • docker run --rm — одноразовый контейнер; после завершения tar контейнер удаляется.
  • -v my_volume:/data монтирует именованный том проекта в /data внутри контейнера.
  • -v $(pwd):/backup монтирует текущий каталог хоста, куда пишется backup.tar.
  • Образ busybox минимален и содержит tar без установки утилит в основной образ приложения.
  • tar cvf создаёт несжатый архив; для сжатия добавляют флаг z (tar czvf) или pipe в gzip.
  • Имя тома my_volume должно совпадать с именем из секции volumes: compose-файла (с префиксом проекта в полном имени на хосте).

Восстановление — распаковка архива обратно в том.


Переменные окружения и секреты

Переменные окружения передают конфигурационные данные в контейнеры. Они заменяют необходимость хардкодить значения в коде или образах.

Параметр environment в сервисе задает статические значения.

environment:
DB_HOST: localhost
DEBUG: "true"

Разбор:

  • Ключ environment задаёт пары имя=значение, видимые процессу внутри контейнера.
  • DB_HOST: localhost внутри контейнера указывает на loopback самого контейнера, а не на сервис db в сети Compose.
  • Для связи между сервисами в DB_HOST указывают имя сервиса из compose (db), а не localhost.
  • Строковые булевы значения в YAML лучше брать в кавычки ("true"), чтобы парсер не интерпретировал их как boolean.
  • Альтернатива — файл env_file: или синтаксис списка - KEY=value для явного формата.

Подстановка значений из внешнего файла .env осуществляется автоматически. Файл должен находиться в той же директории, что и compose.yaml. Команда docker compose up считывает переменные из этого файла.

docker compose up

Разбор:

  • При старте Compose читает файл .env в каталоге проекта и подставляет значения в $&#123;VAR&#125; в compose-файле.
  • Переменные из оболочки ОС имеют приоритет над .env, если не задана другая политика в документации версии CLI.
  • Синтаксис $&#123;DB_HOST:-localhost&#125; задаёт значение по умолчанию, если переменная не определена.
  • Секреты из .env в репозиторий не коммитят; для продакшена предпочтительны secrets: или внешние vault.
  • Команда up применяет итоговую конфигурацию после всех подстановок.

Синтаксис подстановки $\&#123;VARIABLE_NAME\&#125; позволяет использовать значения из файла окружения или переменных ОС. Если переменная не найдена, используется значение по умолчанию $&#123;VARIABLE_NAME:-default_value&#125;.

Секретность данных обеспечивается через использование файлов секретов. Параметр secrets ссылается на файлы с паролями или ключами. Эти файлы монтируются в контейнер в защищенной области памяти.

Файлы секретов хранятся в отдельной директории и не должны попадать в репозиторий кода. Доступ к ним контролируется правами доступа операционной системы.

Приложение получает доступ к секрету через специальный путь внутри контейнера. Это позволяет хранить чувствительные данные вне конфигурационного файла.


Масштабирование и оркестрация

Команда docker compose up --scale запускает несколько экземпляров одного сервиса. Каждый экземпляр получает уникальный номер в имени. Например, web-1, web-2.

docker compose up --scale web=3

Разбор:

  • --scale web=3 поднимает три контейнера сервиса web с именами …-web-1, …-web-2, …-web-3.
  • Публикация одного и того же ports на хосте при нескольких репликах конфликтует — для балансировки нужен отдельный proxy или режим Swarm.
  • Состояние сервиса должно быть stateless; сессии и локальные файлы в репликах не разделяются автоматически.
  • В Compose Specification поле deploy.replicas применяется в Docker Swarm, а не при обычном локальном docker compose up.
  • Для динамического масштабирования по метрикам нужны внешние оркестраторы (Kubernetes, Swarm).

Распределение нагрузки между экземплярами осуществляется балансировщиком. В локальной среде это может быть встроенный механизм Docker или внешний балансировщик.

Параметр deploy.replicas в формате версии 3.x позволяет задать количество реплик для сервиса. Это используется в режиме Swarm Mode, но также поддерживается в некоторых сценариях Compose.

Автомасштабирование требует внешних инструментов или скриптов. Сам по себе Compose не отслеживает нагрузку и не добавляет новые экземпляры динамически.


Безопасность и лучшие практики

Использование фиксированных версий образов (nginx:1.24-alpine) вместо тега latest гарантирует стабильность среды. Обновления происходят контролируемо после тестирования.

Отказ от запуска контейнеров с правами root повышает безопасность. Параметр user: 1000:1000 запускает приложение под обычным пользователем.

Ограничение ресурсов через cpus и memory предотвращает перегрузку хоста одним сервисом.

Регулярное обновление образов защищает от уязвимостей. Инструменты типа dependabot или renovatebot могут автоматически обновлять зависимости.

Изоляция проектов достигается путем размещения файлов compose.yaml в отдельных папках. Каждый проект получает свою сеть и пространство имен.

Избегание хардкода чувствительных данных в файле конфигурации обязательно. Использование .env файлов и секретов является стандартом.


Пример комплексной конфигурации

Ниже представлен пример конфигурации типичного веб-приложения с базой данных и кешированием.

Код ITЗагрузка примера кода…

Разбор:

  • build: . у сервиса app — образ из Dockerfile в корне проекта; порты 3000:3000 публикуют API на хост.
  • depends_on с condition: service_healthy откладывает старт app, пока pg_isready в healthcheck db не вернёт успех.
  • condition: service_started для redis ждёт только запуска контейнера, без проверки готовности Redis.
  • POSTGRES_PASSWORD_FILE читает пароль из смонтированного секрета, а не из plain-text в YAML.
  • Сеть frontend с драйвером bridge объединяет сервисы; DNS-имена db и redis доступны из app.
  • Тома pg_data и redis_data сохраняют данные между пересозданием контейнеров.
  • restart: unless-stopped перезапускает контейнер после сбоя, кроме явной остановки пользователем.

В этом примере:

  • Приложение app зависит от здоровья базы данных. Запуск продолжится только после успешной проверки healthcheck.
  • Пароль базы данных хранится в файле секрета, а не в переменной окружения.
  • Базы данных и Redis используют тома для сохранения данных.
  • Все сервисы находятся в общей сети frontend.
  • Политики перезапуска настроены на автоматический старт после сбоя или перезагрузки системы.

Диагностика и отладка

При возникновении проблем с запуском используйте docker compose config для проверки файла. Ошибки синтаксиса часто становятся причиной неудач.

docker compose config

Разбор:

  • Парсит compose-файл(ы), подставляет переменные из .env и окружения, выводит итоговый YAML.
  • Ошибки синтаксиса YAML или неизвестных ключей приводят к ненулевому коду выхода — удобно в CI перед up.
  • Флаг --quiet подавляет вывод при успехе; --services печатает только имена сервисов.
  • --profiles показывает конфигурацию с учётом указанных профилей (--profile dev).
  • Не создаёт контейнеры — только валидация и нормализация описания.

Логи каждого сервиса доступны через docker compose logs. Анализ логов помогает найти причины падения приложений.

docker compose logs web

Разбор:

  • Выводит stdout/stderr только сервиса web, без смешивания логов остальных сервисов.
  • Без -f команда завершается после вывода накопленных логов; с -f — поток в реальном времени.
  • Временные метки появляются, если в compose для сервиса включён logging с драйвером, поддерживающим метки, или используется флаг --timestamps.
  • Для нескольких сервисов можно указать несколько имён: docker compose logs web db.
  • Ротация и лимит размера логов настраиваются в logging: сервиса или глобально в daemon.json.

Проверка состояния контейнеров выполняется командой docker compose ps. Статус Exited указывает на проблему с запуском или работой.

docker compose ps

Разбор:

  • Показывает контейнеры текущего проекта — имя, команду, статус, опубликованные порты.
  • Up — процесс в контейнере работает; Exited (N) — завершился с кодом N.
  • Имена вида project-web-1 включают префикс проекта и номер реплики при масштабировании.
  • Не показывает остановленные контейнеры, если не передан флаг -a / --all.
  • Удобная быстрая проверка после up -d, что все сервисы действительно запущены.

docker compose exec позволяет войти в оболочку контейнера для ручной диагностики.

docker compose exec web sh

Разбор:

  • exec выполняет процесс внутри уже запущенного контейнера сервиса web.
  • sh — оболочка Alpine/BusyBox; в Debian/Ubuntu-образах чаще bash.
  • Сервис должен быть в состоянии running; для остановленного контейнера используют docker compose run.
  • Рабочая директория и пользователь — как у основного процесса контейнера, если не заданы -u / -w.
  • Переменные окружения сервиса из compose доступны дочернему процессу.

Сетевые проблемы можно проверить через ping или curl внутри контейнера:

docker compose run --rm app ping db

Разбор:

  • run поднимает новый контейнер сервиса app (не переиспользует уже работающий, если не задан --no-recreate).
  • Контейнер подключён к сети проекта — DNS-имя db резолвится во внутренний IP Postgres.
  • ping db проверяет L3-доступность хоста; успешный ping не гарантирует готовность PostgreSQL к SQL.
  • --rm убирает контейнер после выхода из ping.
  • Для интерактивной отладки часто добавляют -it и оболочку вместо ping.

Очистка старых ресурсов выполняется командой docker compose down -v. Это удаляет тома и сети, освобождая место.

docker compose down -v

Разбор:

  • -v — сокращение --volumes: удаляет named volumes проекта, объявленные в compose-файле.
  • Bind-монты (пути вида ./data:/app) не удаляются — очищается только управляемый Docker том.
  • Полезно при отладке "грязной" БД или после смены схемы миграций в dev-среде.
  • Данные в томах после команды восстановить нельзя — перед -v нужна резервная копия, если данные важны.
  • Сети проекта также удаляются вместе с контейнерами.

Типичные проблемы и быстрые проверки

  • Сервис "поднялся", но не отвечает — проверьте healthcheck, readiness и фактический порт приложения внутри контейнера.
  • Ошибка подключения к БД — убедитесь, что в DB_HOST указано имя сервиса (db), а не localhost.
  • Потеря данных — проверьте, что для БД используется named volume, а не только writable-слой контейнера.
  • Конфигурация "не подхватилась" — выполните docker compose config и проверьте итоговый merged YAML.
  • Сборка слишком долгая — перестройте порядок слоёв в Dockerfile и добавьте .dockerignore.

Интеграция в CI/CD

В системах непрерывной интеграции Docker Compose используется для запуска тестов в изолированной среде. Пайплайн выполняет docker compose up --build перед запуском тестов.

docker compose up --build
docker compose run --rm test npm test

Разбор:

  • up --build пересобирает образы с build: перед стартом зависимостей — актуальный код попадает в CI-прогон.
  • run создаёт одноразовый контейнер сервиса test с переопределённой командой (npm test).
  • --rm удаляет контейнер после завершения команды — не засоряет хост остановленными экземплярами.
  • Сервисы из depends_on при run поднимаются по правилам проекта, если не указано --no-deps.
  • Переменные из .env и окружения ОС подставляются так же, как при up.

После завершения тестов среда очищается командой docker compose down. Это гарантирует чистоту следующего запуска.

docker compose down

Разбор:

  • down останавливает и удаляет контейнеры и сети текущего проекта Compose.
  • Named volumes по умолчанию сохраняются — данные БД остаются для следующего up.
  • С --volumes (-v) удаляются тома, объявленные в секции top-level volumes: файла.
  • Образы на диске не удаляются; для очистки образов — docker compose down --rmi local или all.
  • В CI после тестов down гарантирует, что следующий job не увидит "висящие" контейнеры проекта.

Использование параллельной сборки (--parallel) ускоряет процесс в конвейерах.

docker compose build --parallel

Разбор:

  • build собирает образы только для сервисов с ключом build: или с отсутствующим локальным образом при политике pull.
  • --parallel запускает сборку нескольких сервисов одновременно — ускоряет CI при независимых Dockerfile.
  • Не поднимает контейнеры; после сборки обычно следует docker compose up или docker compose push образов в registry.
  • Кэш слоёв Docker переиспользуется между сборками; для "чистой" сборки в пайплайне добавляют --no-cache.
  • Имя образа по умолчанию — проект_сервис; тег задаётся в image: или генерируется при сборке.

Связанные материалы