Alguns comandos como up -d service_name ou start service_name estão retornando imediatamente e isso é muito útil se você não quiser que os contêineres em execução dependam do Estado do shell, como fazem com o normal up service_name. O único caso de uso é executá-lo a partir de algum tipo de servidor de integração/entrega contínuo.
Mas essa maneira de executar/iniciar serviços não fornece nenhum feedback sobre o estado real do serviço posteriormente.
Eu tinha uma necessidade semelhante. No entanto, eu tenho um restart: always no meu ambiente. Portanto, pode ser um pouco complicado detectar se algo está travando e reiniciando em um loop.
Fiz uma verificação Icinga / Nagios para também comparar os horários de criação e início. Talvez seja útil para outra pessoa no futuro:
#!/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)
Isso está retornando apenas o status do contêiner docker. Se você quiser verificar o estado real do seu aplicativo, adicione HEALTHCHECK ao seu Dockerfile (https://docs.docker.com/engine/reference/builder/#healthcheck). Depois, você pode inspecioná-lo com:
os contêineres iniciam e são executados indefinidamente ou param imediatamente com um código de erro (ou seja, para configuração ausente)
você faz a verificação apenas uma vez após o docker-compose up-d retornar
você pode verificar se há algum contêiner parado devido a um erro com:docker ps -a | grep 'Exited (255)'.
Essa verificação funciona corretamente, mesmo no caso de contêineres que devem parar imediatamente sem erro (ou seja, contêineres de dados), como seu status (de docker ps -a) é marcado como Exited (0).
Por exemplo, em nosso docker-compose.yml, começamos nossos contêineres com:
Você pode grep para (healthy) ou / e (unhealthy) imagens para agir corretamente.
Neste exemplo, estou sondando docker-compose a cada 5 segundos para executar o serviço com (healthy) status.Se o script encontrar esse serviço, ele interromperá a execução.Se o script exceder 300 segundos, ele sairá com o código de erro.
#!/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