web-dev-qa-db-fra.com

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

J'utilise le docker-compose.

Certaines commandes comme up -d service_name ou start service_name reviennent tout de suite, ce qui est très 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 _ 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.

Référence CLI Docker Compose pour la commande up mentionne l'option appropriée, mais, comme pour la version 1.7.1, il 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?

24
Ivan Kolmychek
  • 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 ps affiche une version courte des ID par défaut, nous devons donc spécifier --no-trunc drapeau.

UPDATE : Il a lancé l'avertissement "grep usage" 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
18
elquimista

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

Au lieu de cela, le exec peut ê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 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é.

12
Ivan Kolmychek

Tu peux courir:

docker-compose ps -q service-name

Et vous obtiendrez l'id du conteneur si service-name est 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
6
alejandropg

J'avais un besoin similaire. Cependant, j'ai un restart: always dans 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)
2
jof

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.

0
George Mauer

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 existe un conteneur arrêté en raison d'une erreur avec: 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
  '

dotenv_check.js Et dotenv_check.php Sont des scripts qui se terminent avec un code d'erreur au cas où une variable env requise serait manquante.

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

0
Fabio