Некоторые команды, такие как up -d service_name или start service_name возвращаются сразу, и это очень полезно, если вы не хотите, чтобы запущенные контейнеры зависели от состояния оболочки, как это происходит с обычными up service_name. Единственный вариант использования - запустить его с какого-то сервера непрерывной интеграции / доставки.
Но этот способ запуска / запуска служб не дает никакой обратной связи о фактическом состоянии службы впоследствии.
docker-compose ps -q <service_name> будет отображаться идентификатор контейнера независимо от того, запущен он или нет, до тех пор, пока он был создан.
docker ps показывает только те, которые действительно запущены.
Давайте объединим эти две команды:
if [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then echo "No, it's not running."else echo "Yes, it's running."fi
docker ps показывает короткую версию идентификаторов по умолчанию, поэтому нам нужно указать --no-trunc флаг.
ОБНОВЛЕНИЕ: Он выдавал предупреждение "использование grep", если служба не была запущена. Благодаря @Dzhuneyt, вот обновленный ответ.
У меня была похожая потребность. Тем не менее, у меня есть restart: always в моем окружении. Таким образом, может быть немного сложно определить, происходит ли сбой и перезапуск чего-либо в цикле.
Я сделал проверку Icinga / Nagios, чтобы также сравнить время создания и запуска. Может быть, это пригодится кому-то еще в будущем:
#!/usr/bin/env pythonfrom __future__ import print_functionimport argparsefrom datetime import timedeltafrom datetime import datetimeimport sysfrom dateutil.parser import parse as parse_dateimport dockerimport pytzparser = argparse.ArgumentParser()parser.add_argument("compose_project", help="The name of the docker-compose project")parser.add_argument("compose_service", help="The name of the docker-compose service")args = vars(parser.parse_args())client = docker.from_env()service_containers = client.containers.list(filters={ "label": [ "com.docker.compose.oneoff=False", "com.docker.compose.project={}".format(args["compose_project"]), "com.docker.compose.service={}".format(args["compose_service"]) ]})if len(service_containers) == 0: print("CRITICAL: project({})/service({}) doesn't exist!".format( args["compose_project"], args["compose_service"])) sys.exit(2)elif len(service_containers) > 1: print("CRITICAL: project({})/service({}) has more than 1 " "container!".format( args["compose_project"], args["compose_service"])) sys.exit(2)service_container = service_containers[0]created_at = parse_date(service_container.attrs['Created'])status = service_container.attrs['State']['Status']started_at = parse_date(service_container.attrs['State']['StartedAt'])now = datetime.utcnow().replace(tzinfo=pytz.utc)uptime = now - started_atif status in ['stopped', 'exited', 'dead']: print("CRITICAL: project({})/service({}) is status={}".format( args["compose_project"], args["compose_service"], status)) sys.exit(2)if (started_at - created_at) > timedelta(minutes=5): if uptime < timedelta(seconds=5): print("CRITICAL: project({})/service({}) appears to be " "crash-looping".format( args["compose_project"], args["compose_service"])) sys.exit(2)if status == "restarting": print("WARNING: project({})/service({}) is restarting".format( args["compose_project"], args["compose_service"])) sys.exit(1)print ("OK: project({})/service({}) is up for {}".format( args["compose_project"], args["compose_service"], uptime))sys.exit(0)
Это возвращает только статус контейнера docker. Если вы хотите проверить фактическое состояние вашего приложения, вам следует добавить проверку РАБОТОСПОСОБНОСТИ в свой файл Dockerfile (https://docs.docker.com/engine/reference/builder/#healthcheck). После этого вы можете проверить его с помощью:
контейнеры либо запускаются и запускаются на неопределенный срок, либо немедленно останавливаются с кодом ошибки (например, из-за отсутствия конфигурации).
вы выполняете проверку только один раз после возврата docker-compose up -d
вы можете проверить, есть ли какой-либо остановленный контейнер из-за ошибки с помощью:docker ps -a | grep 'Exited (255)'.
Эта проверка работает корректно даже в случае контейнеров, которые, как ожидается, остановятся немедленно без ошибок (т.Е. контейнеров данных), поскольку их статус (из docker ps -a) помечается как Exited (0).
Например, в нашем docker-compose.yml мы начинаем наши контейнеры с:
Вы можете использовать grep для (healthy) или/и (unhealthy) изображения, чтобы действовать должным образом.
В этом примере я проверяю docker-compose каждые 5 секунд для запуска службы с (healthy) статус.Если скрипт найдет такую службу, он прервет выполнение.Если время выполнения скрипта превысит 300 секунд, он завершит работу с кодом ошибки.
#!/bin/bashSECONDS=0LIMIT=300x=$(docker-compose -f /mnt/<service>/docker-compose.yaml ps <service> | grep -c '(healthy)')while [[ $x == "0" ]]; do echo "Please wait until <service> becomes healthy" sleep 5 x=$(docker-compose -f /mnt/<service>/docker-compose.yaml ps <service> | grep -c '(healthy)') EXPIRED=$SECONDS if [[ $x == "1" ]]; then echo "<service> is healthy..." break elif [[ $LIMIT -lt $EXPIRED ]]; then echo "<service> startup has exceeded 5m timeout, exiting!" exit 1 fidone