Гид по технологиям

Управление порядком запуска в Docker Compose

• 6 min read • DevOps • Обновлено 01 Dec 2025
Порядок запуска сервисов в Docker Compose
Порядок запуска сервисов в Docker Compose

Иллюстрация Docker и контейнеров

TL;DR

Docker Compose по умолчанию запускает сервисы параллельно. Чтобы гарантировать порядок запуска, используйте поле depends_on в файле docker-compose.yml, а для реальной готовности сервиса комбинируйте depends_on с healthcheck или внешними утилитами типа wait-for-it. В статье — примеры YAML, рекомендации, чек-листы и варианты отладки.

Быстрые ссылки

  • Основы
  • Ожидание готовности
  • Ожидание успешного завершения
  • Дополнительные инструменты
  • Когда это не работает
  • Чек-листы для ролей
  • Итог

Основы

Docker Compose поддерживает поле

depends_on

в файлах

docker-compose.yml

Сервис может перечислить имена других сервисов в

depends_on

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

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db

  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api

  db:
    image: mysql:8.0

В этом примере поля

depends_on

определяют порядок создания контейнеров: сначала db, затем api и в конце web-app. Зависимости разрешаются рекурсивно: сервис, который объявляет depends_on, запускается после сервисов, от которых он зависит. Если сервис зависит от нескольких сервисов, Compose попытается запустить их в порядке перечисления.

При остановке стека команда

docker-compose stop

пользуется обратным порядком: web-app будет остановлен первым, затем api и в конце db. Это предотвращает ситуацию, когда frontend всё ещё принимает запросы, а backend уже выключен.

Важно: depends_on по умолчанию ждёт только создания контейнера, но не его готовности к обслуживанию.

Ожидание готовности

Поле

depends_on

в базовой форме гарантирует лишь, что зависимый контейнер создан и запущен, но не что приложение внутри него готово принимать запросы. Чтобы дождаться реальной готовности, используйте встроенные healthcheck-ы Docker и указывайте условие service_healthy.

Пример с healthcheck:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
    healthcheck:
      test: ["CMD-SHELL", "curl --fail http://127.0.0.1 || exit 1"]
      interval: 10s
      retries: 5
      start_period: 5s
      timeout: 10s

  web-app:
    image: example.com/web-app:latest
    depends_on:
      api:
        condition: service_healthy

  db:
    image: mysql:8.0

В этом примере для api определён healthcheck, который возвращает успешный статус только когда API отвечает на HTTP-запросы. web-app не будет запущен, пока состояние api не станет healthy. Подсказка: используйте CMD-SHELL в healthcheck для возможности писать более сложные команды.

Советы по healthcheck:

  • Тест должен быть быстрым и идемпотентным. Проверяйте конкретную точку здоровья (health endpoint) вместо общей страницы.
  • Настраивайте start_period, interval, timeout и retries для учета времени прогрева сервисов.
  • Healthcheck исполняется внутри контейнера, значит пути и утилиты должны быть доступны внутри образа.

Ожидание успешного завершения

Иногда зависимость — это контейнер одноразовой задачи (one-off), который должен успешно завершиться перед стартом другого сервиса. Пример: генерация конфига или миграции БД. Для этого используйте condition: service_completed_successfully.

services:
  app:
    image: example.com/app:latest
    depends_on:
      config_builder:
        condition: service_completed_successfully
    volumes:
      - config:/opt/app/config

  config_builder:
    image: example.com/config_builder:latest
    env:
      - EXAMPLE_KEY
      - ANOTHER_KEY
    volumes:
      - config:/output

volumes:
  config:

Здесь config_builder запускается первым, записывает конфигурацию в общий том и корректно завершается. Compose ожидает успешного выхода config_builder и затем запускает app.

Обратите внимание: если config_builder завершится с ненулевым кодом — зависимый сервис не будет запущен.

Дополнительные инструменты

В ситуациях, когда вы не можете добавить healthcheck в образ (например, сторонний образ без утилит), вы можете использовать внешние скрипты и утилиты, которые ждут доступности порта или ответа сервиса. Одним из популярных инструментов является wait-for-it или similar-wait-scripts.

Пример использования wait-for-it в docker-compose:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db

  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api
    command: ["./wait-for-it.sh", "api:8080", "--", "node", "app.js"]

  db:
    image: mysql:8.0

Здесь web-app сам проверяет доступность api на порту 8080 и запускает node app.js только после того, как api отвечает. Такой подход полезен, когда нельзя изменить образ api или прописать в нём healthcheck.

Уточнение по wait-for-it:

  • Это внешняя утилита, которая блокирует запуск основного процесса до достижения условия.
  • Она проверяет лишь достижимость TCP-порта, что не всегда означает готовность приложения (например, порт может быть открыт, но сервис ещё не инициализирован).
  • Подходит как быстрый обходной путь, но лучше реализовать полноценный healthcheck в образе.

Когда depends_on не решает проблему

Несколько типичных ситуаций, когда базовый depends_on недостаточен:

  • Сервис поднят, но не готов обрабатывать запросы (например, миграция БД ещё выполняется).
  • Сторонний образ не имеет необходимых утилит для выполнения healthcheck.
  • Сервис считает себя “готовым” только после выполнения фоновых задач, которые не отражаются на простом TCP-пинговании.

Что делать:

  • Добавьте healthcheck в Dockerfile/образ, если возможно.
  • Используйте one-off контейнеры для инициализации (миграции, генерация конфигов) и condition: service_completed_successfully.
  • Если образ нельзя изменить, используйте обёртки типа wait-for-it или собственные скрипты запуска с логикой проверки.
  • Рассмотрите оркестрацию (Kubernetes), если вам нужна более гибкая логика восстановления и зависимости на уровне приложений.

Отладка и распространённые ошибки

  • Логи healthcheck: смотрите docker inspect –format=’{{json .State.Health}}’ для детального состояния healthcheck.
  • Проверяйте, что команды healthcheck доступны в образе и работают локально.
  • Если depend_on использует condition, убедитесь, что вы используете совместimую версию Compose (v2+ синтаксис vs v3 может отличаться по поддержке условных зависимостей).
  • Не путайте завершение контейнера с безопасным завершением; если контейнер постоянно падает — зависимый сервис не запустится.

Чек-листы для ролей

Разделённый по ролям, краткие списки задач, которые помогут стандартизировать работу при настройке порядка запуска.

Разработчик приложения:

  • Добавить эндпоинт /health или /ready.
  • Написать простой healthcheck, который проверяет реальные зависимости (БД, кеш).
  • Убедиться, что командный образ содержит curl или иной инструмент для проверки.

DevOps-инженер:

  • Добавить healthcheck в docker-compose.yml или Dockerfile.
  • Настроить depends_on с condition: service_healthy при необходимости.
  • Организовать раздельные one-off сервисы для миграций и генерации конфигов.

Тестировщик:

  • Проверить сценарии старта: чистая база, миграции, потеря сети.
  • Воспроизвести падение зависимого сервиса и убедиться, что поведение ожидаемое.
  • Написать автоматические тесты, которые проверяют порядок запуска и доступность конечных точек.

Факт-бокс

  • depends_on по умолчанию проверяет только создание контейнера, а не его внутреннюю готовность.
  • service_healthy требует корректно настроенного healthcheck внутри контейнера.
  • service_completed_successfully полезен для одноразовых задач и миграций.

Модель принятия решения

Ниже — упрощённый поток принятия решения, который поможет выбрать подходящий механизм.

flowchart TD
  A[Нужен порядок запуска?] -->|Нет| B[Запускать параллельно]
  A -->|Да| C[Являются ли зависимости долгоживущими сервисами?]
  C -->|Да| D[Можно ли добавить healthcheck в образ?]
  C -->|Нет| E[Использовать service_completed_successfully]
  D -->|Да| F[Добавить healthcheck и depends_on: service_healthy]
  D -->|Нет| G[Использовать wait-for-it или обёртку в command]

Критерии приёмки

  • Сервисы стартуют в ожидаемом порядке при запуске docker-compose up.
  • Сервисы не падают в процессе старта из-за отсутствия зависимостей.
  • Healthcheck корректно отражает готовность сервиса.
  • One-off контейнеры корректно завершаются с кодом 0, и зависимые сервисы стартуют после этого.

Краткий словарь

  • depends_on: директива Compose для объявления порядка запуска.
  • healthcheck: команда внутри образа для проверки состояния сервиса.
  • service_healthy: условие, что сервис считается ready по результатам healthcheck.
  • service_completed_successfully: условие, когда контейнер завершился с кодом 0.

Частые вопросы

Можно ли заставить depends_on ждать только порт TCP?

Да. Если добавить в образ или команду обёртку вроде wait-for-it, зависимый сервис может проверять доступность TCP-порта и запускать основную команду только после открытия порта.

Что делать с образами, в которых нельзя установить healthcheck?

Используйте внешние скрипты ожидания или создайте вспомогательный контейнер-инициализатор, который проверяет готовность стороннего сервиса.

Зависит ли поведение от версии Compose или формата файла?

Да. Некоторые старые версии docker-compose имели отличия в поддержке условных зависимостей. Рекомендуется использовать современный синтаксис и проверять документацию для вашей версии.

Итог

  • Используйте depends_on для упорядочивания старта контейнеров.
  • Для реальной готовности комбинируйте depends_on с healthcheck и condition: service_healthy.
  • Для одноразовых задач применяйте condition: service_completed_successfully.
  • Если образ нельзя изменить, используйте утилиты ожидания или собственные скрипты.

Важно: настройка порядка запуска — это один из инструментов надёжного развёртывания, но для более сложных сценариев стоит рассмотреть полноценные системы оркестрации и стратегии восстановления.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро