web-dev-qa-db-fra.com

arrêter et supprimer le conteneur Docker s'il est en cours d'exécution

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
35
Robbo_UK

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.

87
Johannes Barop

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
13
ncoghlan

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
  • La commande awk obtient une ligne de commande var app de la variable $app de BASH
  • NR>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 non
12
anubhava

J'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
5
Robbo_UK
# 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
1
iver56

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 )

0
Svend

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
0
Alex Montoya