Остановить и удалить контейнер докера, если его запуск
Я пытаюсь прагматически остановить и удалить контейнер докера, если он запущен. Это для сборки 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)