Я использую RabbitMQ и простой образец питона из здесь вместе с Докером-композом. Моя проблема в том, что мне нужно дождаться полного запуска rabbitmq. Из того, что я искал до сих пор, я не знаю, как ждать с контейнером x (в моем случае рабочий), пока не будет запущен y (rabbitmq).
Я нашел этот блог, где он проверяет, находится ли другой хост в сети. Я также нашел эту команду Docker :
Подождите
Использование: докер подождите КОНТЕЙНЕР [КОНТЕЙНЕР ...]
Блокируйте, пока контейнер не остановится, затем напечатайте его код выхода.
Ожидание остановки контейнера, возможно, не то, что я ищу, но если это так, возможно ли использовать эту команду внутри docker-compose.yml? Мое решение до сих пор состоит в том, чтобы подождать несколько секунд и проверить порт, но так ли это можно сделать? Если я не жду, я получаю ошибку.
докер-compose.yml
worker:
build: myapp/.
volumes:
- myapp/.:/usr/src/app:ro
links:
- rabbitmq
rabbitmq:
image: rabbitmq:3-management
Пример приветствия Python (rabbit.py):
import pika
import time
import socket
pingcounter = 0
isreachable = False
while isreachable is False and pingcounter < 5:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('rabbitmq', 5672))
isreachable = True
except socket.error as e:
time.sleep(2)
pingcounter += 1
s.close()
if isreachable:
connection = pika.BlockingConnection(pika.ConnectionParameters(
host="rabbitmq"))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print (" [x] Sent 'Hello World!'")
connection.close()
Dockerfile для работника:
FROM python:2-onbuild
RUN ["pip", "install", "pika"]
CMD ["python","rabbit.py"]
Обновление ноябрь 2015 :
Сценарий оболочки или ожидание внутри вашей программы, возможно, является возможным решением. Но после просмотра этой проблемы я ищу команду или функцию docker / docker-compose.
Они упоминают о решении для проверки работоспособности, которое может быть лучшим вариантом. Открытое TCP-соединение не означает, что ваш сервис готов или может оставаться готовым. В дополнение к этому мне нужно изменить мою точку входа в моем файле Docker.
Поэтому я надеюсь получить ответ с командами docker-compose на борту, что, будем надеяться, произойдет, если они закончат эту проблему.
Обновление март 2016
Существует предложение по предоставлению встроенного способа определения, является ли контейнер «живым». Так что docker-compose может использовать его в ближайшем будущем.
Обновление июнь 2016
Похоже, что Healthcheck будет интегрирован в Docker в версии 1.12.0
Обновление январь 2017
Я нашел решение docker-compose, см .: Docker Compose ждет контейнера X перед запуском Y
источник
Ответы:
Наконец нашел решение с помощью метода docker-compose. Начиная с формата файла docker-compose 2.1 вы можете определять проверки работоспособности .
Я сделал это в примере проекта, вам нужно установить хотя бы докер 1.12.0+. Мне также нужно было расширить Dockerfile с управлением rabbitmq , потому что curl не установлен на официальном образе.
Теперь я проверяю, доступна ли страница управления rabbitmq-контейнером. Если curl заканчивается с кодом выхода 0, приложение контейнера (python pika) будет запущено и опубликует сообщение в очередь приветствия. Его сейчас работает (выходной).
docker-compose (версия 2.1):
вывод:
Dockerfile (rabbitmq + curl):
Версия 3 больше не поддерживает форму условия depen_on . Таким образом, я перешел от зависит от перезапуска при сбое. Теперь мой контейнер приложения будет перезапускаться 2-3 раза, пока он не заработает, но он все еще остается функцией создания докера без перезаписи точки входа.
docker-compose (версия 3):
источник
ping
использует ICMP, поэтому не поддерживает TCP-порты. Может быть,nc
чтобы проверить порт TCP. Вероятно, лучше использоватьpsql -h localhost -p 5432
и запросить что-то.condition
формаdepends_on
удалена, ноdepends_on
сама по-прежнему присутствует в v3depends_on
сcondition
был удален?Собственно это пока невозможно. Смотрите также этот запрос функции .
Пока что вам нужно сделать это в своих контейнерах,
CMD
чтобы дождаться появления всех необходимых сервисов.В разделе
Dockerfile
sCMD
вы можете обратиться к своему собственному стартовому скрипту, который оборачивает запуск службы контейнеров. Перед тем, как начать, вы ждете такой зависимости, как:Dockerfile
start.sh
Вероятно, вам нужно установить Netcat в вашем
Dockerfile
. Я не знаю, что предустановлено на образ питона.Есть несколько инструментов, которые предоставляют простую в использовании логику ожидания для простых проверок порта tcp:
Для более сложных ожиданий:
источник
Использование
restart: unless-stopped
илиrestart: always
может решить эту проблему.Если работник
container
останавливается, когда rabbitMQ не готов, он будет перезапущен, пока не будет.источник
Совсем недавно они добавили
depends_on
функцию .Редактировать:
Начиная с версии 2.1+ вы можете использовать
depends_on
в сочетании с этимhealthcheck
для достижения этого:Из документов :
До версии 2.1
Вы все еще можете использовать
depends_on
, но это влияет только на порядок, в котором запущены сервисы - но не если они готовы до запуска зависимого сервиса.Кажется, требуется хотя бы версия 1.6.0.
Использование будет выглядеть примерно так:
Из документов:
Примечание: насколько я понимаю, хотя это и устанавливает порядок загрузки контейнеров. Это не гарантирует, что сервис внутри контейнера действительно загружен.
Например, у вас может быть контейнер postgres . Но сам сервис postgres все еще может инициализироваться внутри контейнера.
источник
depends_on
.» docs.docker.com/compose/compose-file/#dependsondepends_on
не ждет, пока контейнер находится вready
состоянии (что бы это ни значило в вашем случае). Он только ждет, пока контейнер не будет в рабочем состоянии.Вы также можете просто добавить его в опцию команды, например.
https://github.com/docker/compose/issues/374#issuecomment-156546513
для ожидания порта вы также можете использовать что-то вроде этого
чтобы увеличить время ожидания, вы можете взломать немного больше:
источник
restart: on-failure
сделал трюк для меня .. см. нижеисточник
Для заказа контейнера начните использовать
Для ожидания предыдущего запуска контейнера используйте скрипт
Эта статья поможет вам https://docs.docker.com/compose/startup-order/
источник
Вы также можете решить эту проблему, установив конечную точку, которая ожидает запуска службы, с помощью netcat (используя сценарий docker-wait ). Мне нравится этот подход, так как у вас все еще есть чистый
command
раздел,docker-compose.yml
и вам не нужно добавлять специфичный для докера код в ваше приложение:Тогда ваш
docker-entrypoint.sh
:В настоящее время это задокументировано в официальной документации докера .
PS: Вы должны установить
netcat
в свой экземпляр докера, если это не доступно. Для этого добавьте это в вашDocker
файл:источник
Есть готовая утилита под названием « docker-wait », которую можно использовать для ожидания.
источник
Пробовал много разных способов, но понравилась простота этого: https://github.com/ufoscout/docker-compose-wait
Идея , что вы можете использовать ENV варов в файл докер письма , чтобы представить список хостов услуг (с портами) , которые должны быть «долгожданный» , как это:
WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017
.Допустим, у вас есть следующий файл docker-compose.yml (копия / история из репозитория README ):
Затем, чтобы службы могли ждать, вам нужно добавить следующие две строки в ваши Dockerfiles (в Dockerfile служб, которые должны ожидать запуска других служб):
Полный пример такого примера Dockerfile (снова из репозитория проекта README ):
Для получения дополнительной информации о возможном использовании см. README.
источник
https://github.com/ufoscout/docker-compose-wait
библиотеку работать :) Способ, которым вы используете эту библиотеку, не меняет ответ, что вы можете использовать некоторую библиотеку. Безопасность - это сложная тема, и если мы пойдем далеко, мы все равно должны проверить, что эта библиотека делает внутри, даже если мы ее КОПИРУЕМ :) Поэтому лучше быть более конкретным в своем комментарии, например: «Я настоятельно рекомендую не использовать эту библиотеку. из гиперссылки ". Надеюсь, вы согласны, спасибо за подсказку!основываясь на этом сообщении в блоге https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html
Я настроил мой,
docker-compose.yml
как показано ниже:Тогда я делаю для запуска =>:
docker-compose up start_dependencies
rabbitmq
Сервис запустится в режиме демона,start_dependencies
завершит работу.источник
"curl", "-f", "http://localhost:15672"
для которого вам нужно установитьmanagement
плагин и использовать Healthcheck, который уже устарел - его лучший ответ. Простой рабочий пример с проверкой черезnc
свой - downvote. ха, хорошо ...docker-compose run --name app-test --rm "app" bash -l -c 'echo Waiting for mysql service start... && while ! nc -z db-server 3306; do sleep 1; done && echo Connected! && /bin/bash /script/ci_tests.sh'
В версии 3 файла Docker Compose вы можете использовать RESTART .
Например:
докер-compose.yml
Обратите внимание, что я использовал зависимость__ вместо ссылок, поскольку последняя версия устарела в версии 3.
Несмотря на то, что это работает, это может быть не идеальным решением, поскольку вы перезапускаете контейнер докера при каждом сбое.
Посмотрите также на RESTART_POLICY . это позволит вам точно настроить политику перезапуска.
Когда вы используете Compose в производственной среде , лучше всего использовать политику перезапуска:
источник
Одним из альтернативных решений является использование решения для оркестровки контейнеров, такого как Kubernetes. В Kubernetes есть поддержка контейнеров init, которые выполняются до завершения, прежде чем другие контейнеры могут запускаться. Вы можете найти пример здесь с контейнером SQL Server 2017 Linux, где контейнер API использует контейнер инициализации для инициализации базы данных
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
источник
Вот пример, где
main
контейнер ожидает,worker
когда он начинает отвечать на запросы ping:Однако правильным способом является использование
healthcheck
(> = 2.1).источник
Не рекомендуется для серьезных развертываний, но здесь, по сути, есть команда "подождите х секунд".
С
docker-compose
версией инструкция была добавлена . Это означает, что мы можем сделать следующее:3.4
start_period
healthcheck
docker-compose.yml
:status.sh
:Здесь происходит то, что
healthcheck
вызывается через 5 секунд. Это вызываетstatus.sh
скрипт, который всегда возвращает «Нет проблем». Мы просто заставилиzmq_client
контейнер ждать 5 секунд перед запуском!Примечание: это важно, что у вас есть
version: "3.4"
. Если.4
нет, docker-compose жалуется.источник
start_period
делает. Эта конфигурация означает, что есть льготный период, когда неудачные проверки работоспособности не считаются повторными попытками. Если это удастся рано, это считается здоровым. После начального периода сбой будет считаться повторной попыткой. См. Docs.docker.com/engine/reference/builder/#healthcheckУ меня просто есть 2 файла композиции, и я начинаю один первый, а второй позже. Мой сценарий выглядит так:
источник