Vérifier si le conteneur / service fonctionne avec docker-compose

22

J'utilise le docker-compose.

Certaines commandes aiment up -d service_nameou start service_nameretournent tout de suite et cela est assez utile si vous ne voulez pas que les conteneurs en cours d'exécution dépendent de l'état du shell, comme ils le font avec regular up service_name. Le seul cas d'utilisation est de l'exécuter à partir d'une sorte de serveur d'intégration / livraison continue.

Mais cette façon de lancer / démarrer les services ne fournit aucun retour sur l'état réel du service par la suite.

La référence CLI de Docker Compose pour la upcommande mentionne l'option appropriée, mais, comme pour la version 1.7.1, elle s'exclut mutuellement avec -d:

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

Puis-je en quelque sorte vérifier manuellement que le conteneur fonctionne bien et ne s'est pas arrêté en raison d'une erreur?

Ivan Kolmychek
la source

Réponses:

15
  • docker-compose ps -q <service_name> affichera l'ID du conteneur, qu'il soit en cours d'exécution ou non, tant qu'il a été créé.
  • docker ps affiche uniquement ceux qui sont réellement en cours d'exécution.

Combinons ces deux commandes:

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 psaffiche une version courte des ID par défaut, nous devons donc spécifier l' --no-truncindicateur.

MISE À JOUR : Il a lancé un avertissement "utilisation grep" si le service n'était pas en cours d'exécution. Merci à @Dzhuneyt, voici la réponse mise à jour.

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
la source
Nice one, et il résout également le problème avec la réponse actuelle qui a été déclarée dans les commentaires. Marquer cela comme une nouvelle réponse.
Ivan Kolmychek
1
Si vous utilisez une politique de redémarrage, vous devez également la filtrer pour n'inclure que les conteneurs en cours d'exécution (plutôt que ceux en état de redémarrage):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Max
1
Cela fonctionne mais génère un avertissement "utilisation de grep" si le service n'est pas en cours d'exécution, en d'autres termes, lorsque la grep ....pièce se retrouve avec une chaîne vide.
Dzhuneyt
@Dzhuneyt Je sais, oui, vous avez raison. Réflexions sur pour éviter / gérer cet avertissement grep?
elquimista
1
@elquimista Oui, je l' ai résolu en utilisant l'opérateur OR: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Ce que cela signifie: il vérifie d'abord si le service existe (même s'il est arrêté) et la deuxième partie vérifie si le service existant est réellement en cours d'exécution. Vous voudrez peut-être l'inclure dans votre exemple pour les futurs lecteurs qui ne regardent que la réponse acceptée. Je pense que c'est utile.
Dzhuneyt
12

Quant à la version 1.7.1, il n'y a pas de telles commandes intégrées.

Au lieu de cela, le execpeut être utilisé de la même manière.

Lorsque vous l'exécutez pour le service qui contient des conteneurs, il fonctionnera correctement:

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

Mais lorsque vous l'exécutez pour le service qui n'a aucun conteneur de service en cours d'exécution , il affiche une erreur:

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

Ainsi, il peut être utilisé pour vérifier s'il existe des conteneurs "vivants" pour un service donné.

Ivan Kolmychek
la source
5

Tu peux courir:

docker-compose ps -q service-name

Et vous obtiendrez l'identifiant du conteneur s'il service-nameest en cours d'exécution. Quelque chose comme:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Si le service n'est pas en cours d'exécution, la sortie est vide, donc si vous souhaitez l'utiliser dans un script, vous pouvez faire quelque chose comme:

IS_RUNNING=`docker-compose ps -q service-name`
if [[ "$IS_RUNNING" != "" ]]; then
    echo "The service is running!!!"
fi
alejandropg
la source
Oui, ça marche aussi. Marqué ceci comme réponse maintenant.
Ivan Kolmychek
12
Cela ne vous dit pas si le conteneur est en cours d'exécution ou non, juste s'il existe ou non. Essayez de faire docker-compose upensuite Ctrl-C. docker-compose psdevrait alors montrer que les états du conteneur ne sont pas "Up", mais docker-compose ps -q service-namevous donne toujours un identifiant.
djanderson
2

J'avais un besoin similaire. Cependant, j'en ai un restart: alwaysdans mon environnement. Il peut donc être un peu difficile de détecter si quelque chose plante et redémarre en boucle.

J'ai fait un contrôle Icinga / Nagios pour comparer également les heures de création et de démarrage. Peut-être que c'est utile à quelqu'un d'autre sur la ligne:

#!/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
la source
0

Si vous supposez ce scénario:

  • les conteneurs démarrent et s'exécutent indéfiniment ou s'arrêtent immédiatement avec un code d'erreur (c'est-à-dire pour une configuration manquante)
  • vous ne faites la vérification qu'une seule fois après le retour de docker-compose up -d

vous pouvez vérifier s'il y a un conteneur arrêté en raison d'une erreur: docker ps -a | grep 'Exited (255)'.

Cette vérification fonctionne correctement même dans le cas de conteneurs qui devraient s'arrêter immédiatement sans erreur (c'est-à-dire des conteneurs de données), car leur état (de docker ps -a) est marqué comme Exited (0).

Par exemple, dans notre docker-compose.yml, nous commençons nos conteneurs avec:

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

Pour php-fpm, nous utilisons une commande similaire:

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

Les dotenv_check.jset dotenv_check.phpsont des scripts qui se terminent avec un code d'erreur au cas où une variable env requise serait manquante.

La set -ecommande indique au script de s'arrêter en cas d'erreur, ce qui, à son tour, arrête immédiatement le conteneur. À propos de set-e

Fabio
la source
0

Que dis-tu de ça?

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

vous listez les processus, sélectionnez les lignes où "Up" est dans la colonne 4 et filtrez pour une correspondance sur le nom du service.

George Mauer
la source