Je cherche à arrêter et supprimer de manière pragmatique un conteneur Docker s'il est en cours d'exécution. Ceci est pour un script de construction.
Prenons l'exemple suivant. Comment pourrais-je arrêter et supprimer le conteneur de menu fixe "rabbitmq" comme indiqué dans la colonne NAMES dans un script bash.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9909a5e2856f rabbitmq-image "/docker-entrypoint.s" 11 minutes ago Up 11 minutes 0.0.0.0:5672->5672/tcp, rabbitmq
8990dd1fe503 redis-image "/entrypoint.sh redis" 6 weeks ago Up 4 days 0.0.0.0:32770->6379/tcp redis
etc
La commande suivante va supprimer le conteneur et fait ce que je cherche à faire
docker stop rabbitmq && docker rm -f rabbitmq
Cependant, il s’agit de le combiner dans un script que je voudrais savoir. Je pense que cela ressemblerait à quelque chose comme ça.
#!/bin/bash
if [ /*docker ps check some value */ ]; then
docker stop rabbitmq && docker rm -f rabbitmq
fi
Comme vous l'avez probablement remarqué, docker stop
ainsi que docker rm
se terminent par un code d'état indiquant un échec si le conteneur n'existe pas ou n'est pas en cours d'exécution. Cela entraîne l'échec de votre construction.
Si vous pouvez gérer les messages d'erreur dans votre journal de construction, vous pouvez utiliser cette astuce pour éviter l'échec de la commande Shell:
docker stop rabbitmq || true && docker rm rabbitmq || true
Si l'une des commandes de docker échoue, on appelle true
qui se termine toujours par un code de statut indiquant le succès.
J'ai un problème similaire, mais je n'ai pas aimé la réponse acceptée, car elle supprime les erreurs toutes des commandes, plutôt que simplement l'erreur "introuvable".
Cependant, docker ps -q --filter "name=rabbitmq"
ne produit une sortie que si un conteneur de ce nom existe réellement, donc inspiré par Teste si une commande génère une chaîne vide I est venu avec:
docker ps -q --filter "name=rabbitmq" | grep -q . && docker stop rabbitmq && docker rm -fv rabbitmq
La commande suivante est également utile pour tester les définitions de filtre:
docker ps -q --filter "name=rabbitmq" | grep -q . && echo Found || echo Not Found
Mon cas d'utilisation actuel consistait à définir une paire de tâches Ansible qui supprimaient tous les conteneurs existants (qu'ils soient en cours d'exécution ou non) d'une liste de noms générés dans une tâche antérieure:
- name: Check for containers that actually exist
Shell: 'docker ps -aq --filter "name={{ item }}"'
with_items:
- '{{ previous_command.stdout_lines }}'
register: found_containers
- name: Remove the containers found by the above command
Shell: 'docker stop {{ item.item }} && docker rm -fv {{ item.item }}'
with_items: '{{ found_containers.results }}'
when: item.stdout
Vous pouvez utiliser:
app="rabbitmq"
if docker ps | awk -v app="$app" 'NR > 1 && $NF == app{ret=1; exit} END{exit !ret}'; then
docker stop "$app" && docker rm -f "$app"
fi
awk
obtient une ligne de commande var app
de la variable $app
de BASHNR>1
ignore la première ligne d'en-tête de la commande docker ps
. $(NF) == app
Comparez la dernière colonne NAMES
est égal à variable d'application ou nonJ'utilise docker depuis un moment maintenant. C’est ma méthode préférée pour arrêter et supprimer un conteneur Docker.
docker rm -f || true
# Stop the running "rabbitmq" container if there is one
CONTAINER_NAME="rabbitmq"
OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")"
if [ -n "$OLD" ]; then
docker stop $OLD && docker rm $OLD
fi
Si vous ne supprimez pas vos conteneurs arrêtés, un autre moyen simple de résoudre ce problème consiste à utiliser docker ps -a
, qui renvoie toujours cet ID de conteneur. Ensuite, exécuter docker stop
sur ce conteneur arrêté ne fera rien, simplement:
docker stop $(docker ps -a --filter name= rabbitmq -q )
Copiez ce code dans votre script.sh si vous voulez stop
et remove
all
#!/bin/sh
ids=$(docker ps -a -q)
for id in $ids
do
echo "$id"
docker stop $id && docker rm $id
done