Остановить и удалить контейнер докера, если его запуск

Я пытаюсь прагматически остановить и удалить контейнер докера, если он запущен. Это для сборки script.

Возьмем следующий пример. Как я могу остановить и удалить контейнер-докер "rabbitmq", как показано в столбце NAMES в bash script.

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 

Следующая команда удалит контейнер и сделает то, что им нужно сделать

docker stop rabbitmq && docker rm -f rabbitmq

Однако его расчесывание в script, что я хотел бы знать? Я думаю, что это будет выглядеть примерно так.

#!/bin/bash

if [ /*docker ps check some value */ ]; then
   docker stop rabbitmq && docker rm -f rabbitmq
fi

Ответы

Ответ 1

Как вы, вероятно, заметили, docker stop, а также docker rm выйти со статусом, указывающим на сбой, если контейнер не существует или не работает. Это приводит к сбою сборки.

Если вы можете справиться с сообщениями об ошибках в журнале сборки, вы можете сделать этот небольшой трюк, чтобы предотвратить потерю команды оболочки:

docker stop rabbitmq || true && docker rm rabbitmq || true

В случае сбоя одной из команд docker вызывается true, который всегда выходит с кодом состояния, указывающим успех.

Ответ 2

У меня есть аналогичная проблема, но мне не нравится принятый ответ, поскольку он подавляет все ошибки из команд, а не только ошибку "не найден".

Однако docker ps -q --filter "name=rabbitmq" создает только выходные данные, если контейнер этого имени существует, поэтому он вдохновлен Проверить, выводит ли команда пустую строку. Я придумал:

docker ps -q --filter "name=rabbitmq" | grep -q . && docker stop rabbitmq && docker rm -fv rabbitmq

Следующая команда также полезна для тестирования определений фильтров:

docker ps -q --filter "name=rabbitmq" | grep -q . && echo Found || echo Not Found

Мой фактический прецедент заключался в определении пары задач Ansible, которые удалили все существующие в настоящее время контейнеры (независимо от того, запущен или нет) из списка имен, сгенерированных в более ранней задаче:

- 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

Ответ 3

Вы можете использовать:

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 получает командную строку var app из BASH variable $app
  • NR>1 пропускает первую строку заголовка из команды docker ps.
  • $(NF) == app Сравнение последнего столбца NAMES равно переменной приложения или нет

Ответ 4

Уже давно пользуюсь докером. Это мой предпочтительный способ остановить и удалить контейнер докера. Трубка истины есть, чтобы гарантировать, что это всегда приводит к успеху. Без этого любые bash-скрипты выходили бы и выдавали ошибку, если бы имя контейнера не существовало.

docker rm -f container_name || true

Ответ 5

# 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

Ответ 6

Я предлагаю это заклинание в Bash:

( docker stop $CONTAINER > /dev/null && echo Stopped container $CONTAINER && \
  docker rm $CONTAINER ) 2>/dev/null || true

Он всегда завершается с 0, не жалуется, если контейнер не запущен, и печатает Stopped container $CONTAINER если он действительно был остановлен.

Ответ 7

Скопируйте этот код в свой script.sh, если хотите stop и remove все

#!/bin/sh
ids=$(docker ps -a -q)
for id in $ids
do
  echo "$id"
  docker stop $id && docker rm $id
done

Ответ 8

Если вы не удаляете свои остановленные контейнеры, другой простой способ решить эту проблему - использовать docker ps -a, который всегда будет возвращать этот идентификатор контейнера. Тогда выполнение docker stop на этом остановленном контейнере идемпотентно ничего не сделает:

docker stop $(docker ps -a --filter name= rabbitmq -q )

Ответ 9

чтобы остановить все контейнеры, сначала нужно остановить все контейнеры с помощью

docker kill $(docker ps -q)

и удалить все контейнеры

docker rm $(docker ps -a -q)

и если вы хотите удалить все изображения, это команда

docker rmi $(docker images -q)