Überprüfen Sie, ob Container / Dienst mit docker-compose ausgeführt wird

Ich benutze das docker-compose.

Einige Befehle wie up -d service_name oder start service_name dies ist ziemlich nützlich, wenn Sie nicht möchten, dass die ausgeführten Container vom Status der Shell abhängen, wie dies bei regulären Containern der Fall ist up service_name. Der einzige Anwendungsfall besteht darin, es von einer Art kontinuierlichem Integrations- / Bereitstellungsserver aus auszuführen.

Diese Art des Ausführens / Startens von Diensten gibt jedoch keine Rückmeldung über den tatsächlichen Status des Dienstes danach.

Der Docker Compose CLI-Referenz für up Befehl erwähnt die relevante Option, aber wie für die Version 1.7.1, es schließt sich gegenseitig aus mit -d:

--abort-on-container-exit  Stops all containers if any container was stopped.                           *Incompatible with -d.*

Kann ich irgendwie manuell überprüfen, ob der Container tatsächlich funktioniert und nicht aufgrund eines Fehlers angehalten wurde?

  • docker-compose ps -q <service_name> zeigt die Container-ID an, unabhängig davon, ob sie ausgeführt wird oder nicht, solange sie erstellt wurde.
  • docker ps zeigt nur diejenigen an, die tatsächlich ausgeführt werden.

Kombinieren wir diese beiden Befehle:

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 zeigt standardmäßig eine kurze Version von IDs an, daher müssen wir Folgendes angeben --no-trunc Flagge.

UPDATE: Es wurde eine Warnung "grep usage" ausgegeben, wenn der Dienst nicht ausgeführt wurde. Danke an @Dzhuneyt, hier ist die aktualisierte Antwort.

if [ -z `docker-compose ps -q <service_name>` ] || [ -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

Wie für die Version 1.7.1, es sind keine solchen Befehle eingebaut.

Stattdessen wird die exec kann in ähnlicher Weise verwendet werden.

Wenn Sie es für den Dienst ausführen, für den einige Container eingerichtet sind, wird es in Ordnung ausgeführt:

~/apperture-science $ docker-compose exec chell echo 'Still alive!'Still alive!~/apperture-science $ echo $?0

Aber wenn Sie es für den Dienst ausführen, der nicht ausgeführt wird Service andernfalls wird ein Fehler angezeigt:

~/apperture-science $ docker-compose exec glados echo "Still alive!"ERROR: No container found for apperture-science-glados_1~/apperture-science $ echo $?1

Es kann also verwendet werden, um zu überprüfen, ob es "lebende" Container für einen bestimmten Dienst gibt.

Sehen aller laufende Dienste:

docker-compose ps --services --filter "status=running"

Um zu sehen, ob ihr-service läuft:

docker-compose ps --services --filter "status=running" | grep <your-service>

Beachten Sie, dass --filter muss verwendet werden mit --services aus irgendeinem fremden Grund.

Du kannst rennen:

docker-compose ps -q service-name

Und Sie erhalten die ID des Containers, wenn service-name läuft. So etwas wie:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Wenn Sie dies also in einem Skript verwenden möchten, können Sie Folgendes tun:

IS_RUNNING=`docker-compose ps -q service-name`if [[ "$IS_RUNNING" != "" ]]; then    echo "The service is running!!!"fi

Ich hatte ein ähnliches Bedürfnis. Ich habe jedoch eine restart: always in meiner Umgebung. Es kann also etwas schwierig sein zu erkennen, ob etwas abstürzt und in einer Schleife neu startet.

Ich habe einen Icinga / Nagios-Check durchgeführt, um auch die Erstellungs- und Startzeiten zu vergleichen. Vielleicht ist es für jemand anderen auf der ganzen Linie nützlich:

#!/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)

Hier ist ein einfacher Einzeiler, der den aktuellen Status des Dienstes zurückgibt:

docker inspect --format "{{.State.Status}}" $(docker-compose ps -q your_service_name)

Dies gibt nur den Status des Docker-Containers zurück. Wenn Sie den tatsächlichen Status Ihrer Anwendung überprüfen möchten, sollten Sie HEALTHCHECK zu Ihrer Docker-Datei hinzufügen (https://docs.docker.com/engine/reference/builder/#healthcheck). Danach können Sie es inspizieren mit:

docker inspect --format "{{.State.Health.Status}}" $(docker-compose ps -q your_service_name)

Wie wär's damit?

docker-compose ps | awk '$4 == "Up" {print $1}' | grep <service-name>

sie listen die Prozesse auf, wählen die Zeilen aus, in denen "Up" in Spalte 4 steht, und filtern nach einer Übereinstimmung des Dienstnamens.

Wenn Sie dieses Szenario annehmen:

  • container starten und laufen entweder unbegrenzt oder stoppen sofort mit einem Fehlercode (z. B. für fehlende Konfiguration)
  • sie führen die Prüfung nur einmal durch, nachdem docker-compose up -d zurückgegeben wurde

sie können überprüfen, ob ein Container aufgrund eines Fehlers gestoppt wurde mit:docker ps -a | grep 'Exited (255)'.

Diese Prüfung funktioniert auch bei Containern, von denen erwartet wird, dass sie sofort fehlerfrei anhalten (dh Datencontainer), korrekt, da ihr Status (von docker ps -a) ist gekennzeichnet als Exited (0).

Zum Beispiel in unserem Docker-Compose.yml, wir beginnen unsere Container mit:

command: sh -c 'node dotenv_check.js && pm2 start --no-daemon src/worker.js --watch'

Für php-fpm verwenden wir einen ähnlichen Befehl:

command: >-  sh -c '  set -e;  for PROJECT in frontend backend; do    cd /var/www/$${PROJECT};    php dotenv_check.php;  done;  php-fpm  '

Der dotenv_check.js und dotenv_check.php sind Skripte, die mit einem Fehlercode beendet werden, falls eine erforderliche Umgebungsvariable fehlt.

Der set -e befehl, weist das Skript an, bei einem Fehler anzuhalten, was wiederum den Container sofort stoppt. Über set-e

Hier ist ein vereinfachter Einzeiler, der auf almquistas Antwort basiert:

docker ps -q --no-trunc | grep -q "^$(docker-compose ps -q app-service)$"

Wir verwenden Greps -q ein Exit-Code ungleich Null zeigt an, dass der Dienst nicht ausgeführt wird. Beispielsweise:

if docker ps -q --no-trunc | grep -q "^$(dc-audo-dev ps -q app-service)$"; then    echo "Container is still running..."fi