Поиск по сайту:

Как заставить Docker Compose ждать контейнеров зависимостей


Хотя этого не всегда достаточно. Некоторые из ваших контейнеров могут иметь зависимости друг от друга, которые нарушают работу приложения, если они не могут быть выполнены. В этом руководстве мы покажем, как настроить службы Compose для учета этих зависимостей, что позволит запускать контейнеры по порядку.

Основы

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 вызывают запуск служб в следующем порядке:

  • дб
  • API
  • веб-приложение

Зависимости каждой службы разрешаются рекурсивно. Служба, определяющая каждое поле depends_on, запускается последней, в самом конце цепочки. Когда служба зависит от нескольких других контейнеров, они будут запущены в том порядке, в котором они перечислены в поле depends_on.

Цепочка сервисов используется в обратном порядке, когда вы останавливаете стек с помощью docker-compose stop. В приведенном выше примере сначала будет удален контейнер web-app, затем api и db. Это предотвращает сбой запросов к контейнеру web-app в начале операции удаления.

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

Конфигурация depends_on по умолчанию ожидает только запуска зависимых контейнеров. В приведенном выше примере Compose может создать контейнер api сразу после запуска db, даже если сервер базы данных внутри контейнера не готов принимать подключения. Это означает, что depends_on редко бывает достаточно.

Вы можете комбинировать эту функцию с проверками работоспособности, чтобы предотвратить запуск контейнеров, пока их зависимости не будут фактически готовы. Чтобы использовать эту возможность, вложите поле condition в depends_on со значением service_healthy:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
    healthcheck:
      test: 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 прикреплена команда проверки работоспособности. Служба веб-приложения получает указание не запускаться до тех пор, пока не будет создан api с успешным результатом проверки работоспособности. Это произойдет после того, как API начнет отвечать на запросы и команда curl завершится с нулевым кодом состояния.

Ожидание успешного выхода из контейнера

В некоторых случаях ваша зависимость может быть одноразовым контейнером, который вы хотите запустить до завершения. Вы можете дождаться такой зависимости, установив в поле 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:

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

Больше контроля с другими инструментами

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

Wait-for-It — это служебный скрипт, который обертывает другой процесс. Он запустит указанную вами команду после выполнения определенного условия. Это можно использовать для определения процедур проверки работоспособности независимо от встроенной поддержки Docker.

Вот как использовать healthcheck, чтобы дождаться, пока связанный порт контейнера станет доступным:

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

Здесь мы вернулись к тому, что Docker Compose только ожидает запуска контейнера api. Служба веб-приложение берет на себя ответственность за проверку работоспособности api. Он использует скрипт Wait-for-It, чтобы определить, когда контейнер доступен через порт 8080. Затем Wait-for-It запустит реальную команду контейнера веб-приложения, определенную как node app.js.

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

Краткое содержание

Docker Compose по умолчанию одновременно запускает все службы в вашем стеке. Это часто нежелательно, когда связи между службами создают отношения зависимости родитель-потомок.

Поле depends_on позволяет определить последовательность запуска ваших служб. Compose создаст каждый новый контейнер по порядку, гарантируя, что предыдущий будет запущен до того, как будет добавлен следующий контейнер.

Вы можете дождаться завершения работы предыдущего контейнера или сообщить о положительной проверке работоспособности, добавив условие в определение зависимости. В ситуациях, когда проверка работоспособности не может быть использована, вы можете положиться на такие инструменты, как Wait-for-It, чтобы родительские контейнеры определяли, когда их зависимости готовы.




Все права защищены. © Linux-Console.net • 2019-2024