Sur une machine Jenkins, j'aimerais créer un conteneur Docker avec un nom spécifié uniquement s'il n'existe pas déjà (dans un script Shell). J'ai pensé que je pourrais exécuter la commande pour créer le conteneur quand même et ignorer l'échec s'il y en avait un, mais cela entraîne l'échec de mon travail jenkins.
Par conséquent, je voudrais savoir comment je peux vérifier si un conteneur docker existe ou non avec bash.
Vous pouvez vérifier la non-existence d'un conteneur en cours de fonctionnement en effectuant un grepping pour un <name>
et en le lançant ultérieurement comme suit:
[ ! "$(docker ps -a | grep <name>)" ] && docker run -d --name <name> <image>
Mieux:
Utilisez https://docs.docker.com/engine/reference/commandline/ps/ et vérifiez si un conteneur supprimé bloque afin que vous puissiez le supprimer avant d'exécuter le conteneur:
if [ ! "$(docker ps -q -f name=<name>)" ]; then
if [ "$(docker ps -aq -f status=exited -f name=<name>)" ]; then
# cleanup
docker rm <name>
fi
# run your container
docker run -d --name <name> my-docker-image
fi
Vous pouvez utiliser les options filter
et format
de la commande docker ps
pour éviter les tuyaux avec des utilitaires unix tels que grep
, awk
etc.
name='nginx'
[[ $(docker ps --filter "name=^/$name$" --format '{{.Names}}') == $name ]] ||
docker run -d --name mynginx <nginx-image>
Je suppose
docker container inspect <container-name> || docker run...
puisque l'appel de conteneur docker inspectera la valeur $? à 1 si le conteneur n'existe pas (ne peut pas être inspecté) mais à 0 s'il existe (cela concerne les conteneurs arrêtés). Ainsi, la commande d'exécution sera simplement appelée si le conteneur n'existe pas comme prévu.
Préfixez simplement le nom avec ^/et le suffixe avec $. Il semble que ce soit une expression régulière:
CONTAINER_NAME='mycontainername'
CID=$(docker ps -q -f status=running -f name=^/${CONTAINER_NAME}$)
if [ ! "${CID}" ]; then
echo "Container doesn't exist"
fi
unset CID
Encore plus court avec docker top :
docker top <name> || docker run --name <name> <image>
docker top
renvoie non nul si aucun conteneur ne correspond au nom en cours d'exécution, sinon renvoie le pid, l'utilisateur, le temps d'exécution et la commande.
Robuste grep ^$
sans comportement non documenté
C'est l'approche la plus précise et la plus flexible que j'ai pu trouver:
container_name=mycont
if Sudo docker ps -a --format '{{.Names}}' | grep -Eq "^${container_name}\$"; then
echo exists
else
echo 'does not exist'
fi
Raisonnement:
docker container inspect
et que -f name
prend des expressions régulières de quelque sorte.Python
Une version Python pour plus de commodité, car je l'ai utilisée dans un projet:
containers = subprocess.check_output([
'Sudo',
'docker',
'ps',
'-a',
'--format', '{{.Names}}',
]).decode()
if container_name in containers.split():
# Exists.
if [[ $(Sudo docker inspect --format . <container-name>) == "." ]]; then
docker run <container-name>;
fi
Explication :
Il y a déjà une réponse similaire. La différence ici réside dans l'option --format .
(vous pouvez également utiliser -f .
). Cela supprime tous les détails de la commande inspect. Docker utilise le go template format , ce qui signifie qu'il va copier dans la sortie tout ce qu'il ne reconnaît pas.
Donc, -f itIsThere
renverra itIsThere
si un conteneur portant ce nom existe. Si ce n'est pas le cas, docker renverra un code d'erreur et un message (Error: No such object: <container-name>
).
J'ai trouvé celui-ci dans les journaux de Jenkins.
J'utilise le code suivant pour déterminer si le conteneur docker existe:
CONTAINER_NAME='my_docker_container'
# Checking if docker container with $CONTAINER_NAME name exists.
COUNT=$(docker ps -a | grep "$CONTAINER_NAME" | wc -l)
if (($COUNT > 0)); then
echo 'container exists'
fi