Überprüfen Sie, ob der Container / Dienst mit Docker-Compose ausgeführt wird

22

Ich benutze die docker-compose.

Einige Befehle wie up -d service_nameoder start service_namekehren sofort zurück, und dies ist sehr nützlich, wenn die ausgeführten Container nicht vom Status der Shell abhängen sollen, wie dies bei regulären Befehlen der Fall ist up service_name. Der eine Anwendungsfall besteht darin, es von einer Art kontinuierlichem Integrations- / Bereitstellungsserver auszuführen.

Diese Art der Ausführung / des Starts von Diensten gibt jedoch keine Rückmeldung über den aktuellen Status des Dienstes.

In der Docker Compose CLI-Referenz für den upBefehl wird die entsprechende Option zwar erwähnt 1.7.1, sie schließt sich jedoch in Bezug auf die Version 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 aufgrund eines Fehlers nicht angehalten wurde?

Ivan Kolmychek
quelle

Antworten:

15
  • 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 die an, die gerade laufen.

Lassen Sie uns diese beiden Befehle kombinieren:

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 psZeigt standardmäßig eine kurze Version der IDs an, daher müssen wir --no-truncflag angeben .

UPDATE : Es wurde die Warnung "grep usage" ausgegeben, wenn der Dienst nicht ausgeführt wurde. Dank @Dzhuneyt ist hier 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
elquimista
quelle
Nizza, und es behebt auch das Problem mit der aktuellen Antwort, die in den Kommentaren angegeben wurde. Dies als neue Antwort markieren.
Ivan Kolmychek
1
Wenn Sie eine Neustartrichtlinie verwenden, müssen Sie diese auch so filtern, dass nur Container ausgeführt werden (und nicht solche, die sich in einem Neustartzustand befinden):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Max.
1
Dies funktioniert, gibt jedoch eine "grep usage" -Warnung aus, wenn der Dienst nicht ausgeführt wird, dh wenn der grep ....Teil eine leere Zeichenfolge enthält.
Dzhuneyt
@ Dzhuneyt Ich weiß, ja, du hast recht. Überlegungen, diese Grep-Warnung zu vermeiden / zu handhaben?
Elquimista
1
@elquimista Ja, ich löste es die OR - Operator: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Dabei wird zunächst geprüft, ob der Dienst überhaupt vorhanden ist (auch wenn er gestoppt ist), und im zweiten Teil wird geprüft, ob der vorhandene Dienst tatsächlich ausgeführt wird. Möglicherweise möchten Sie dies in Ihr Beispiel für zukünftige Leser aufnehmen, die nur einen Blick auf die akzeptierte Antwort werfen. Ich denke es ist nützlich.
Dzhuneyt
12

Für die Version 1.7.1sind keine derartigen Befehle integriert.

Stattdessen execkann das in ähnlicher Weise verwendet werden.

Wenn Sie es für den Dienst ausführen, für den einige Container verfügbar sind, wird es ordnungsgemäß ausgeführt:

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

Wenn Sie es jedoch für den Dienst ausführen, für den keine Dienstcontainer ausgeführt werden , 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 "lebendige" Container für einen bestimmten Dienst vorhanden sind.

Ivan Kolmychek
quelle
5

Du kannst rennen:

docker-compose ps -q service-name

Und Sie erhalten die ID des Containers, wenn ausgeführt service-namewird. So etwas wie:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Wenn der Dienst nicht ausgeführt wird, ist die Ausgabe leer. 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
Alejandropg
quelle
Ja das geht auch Markierte dies jetzt als Antwort.
Ivan Kolmychek
12
Dies sagt Ihnen nicht, ob der Container läuft oder nicht, nur ob er existiert oder nicht. Versuchen Sie es mit docker-compose upStrg-C. docker-compose pssollte dann zeigen, dass die Containerzustände nicht "Up" sind, aber docker-compose ps -q service-nametrotzdem eine ID geben.
Djanderson
2

Ich hatte ein ähnliches Bedürfnis. Ich habe jedoch eine restart: alwaysin 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 erstellten und Startzeiten zu vergleichen. Vielleicht ist es für jemanden auf der ganzen Linie nützlich:

#!/usr/bin/env python
from __future__ import print_function
import argparse
from datetime import timedelta
from datetime import datetime
import sys

from dateutil.parser import parse as parse_date
import docker
import pytz
parser = 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_at

if 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)
jof
quelle
0

Wenn Sie dieses Szenario annehmen:

  • Container starten und laufen entweder auf unbestimmte Zeit oder stoppen sofort mit einem Fehlercode (dh bei fehlender Konfiguration)
  • Sie führen die Überprüfung nur einmal durch, nachdem docker-compose up -d zurückgegeben hat

Sie können überprüfen , ob es irgendwelche gestoppt Behälter aufgrund eines Fehlers ist mit: docker ps -a | grep 'Exited (255)'.

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

In unserer docker-compose.yml beginnen wir unsere Container beispielsweise 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
  '

Das dotenv_check.jsund dotenv_check.phpsind Skripte, die mit einem Fehlercode beendet werden, falls eine erforderliche Umgebungsvariable fehlt.

Der set -eBefehl weist das Skript an, bei einem Fehler anzuhalten, wodurch der Container sofort angehalten wird. Über set-e

Fabio
quelle
0

Wie wäre es 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 mit dem Dienstnamen.

George Mauer
quelle