Я хочу прагматично остановить и удалить контейнер докера, если он запущен. Это для сценария сборки.
Возьмем следующий пример. Как мне остановить и удалить докер-контейнер rabbitmq, как показано в столбце NAMES в сценарии 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
Следующая команда удалит контейнер и сделает то, что я хочу сделать.
docker stop rabbitmq && docker rm -f rabbitmq
Однако он объединяет это в сценарий, который я хотел бы знать? Думаю, это будет выглядеть примерно так.
#!/bin/bash
if [ /*docker ps check some value */ ]; then
docker stop rabbitmq && docker rm -f rabbitmq
fi
источник
Error response from daemon: no such id: rabbitmq
когда контейнер уже удален.У меня аналогичная проблема, но мне не понравился принятый ответ, поскольку он подавляет все ошибки команд, а не только ошибку «не найдено».
Однако
docker ps -q --filter "name=rabbitmq"
выводит результат только в том случае, если контейнер с таким именем действительно существует, поэтому, вдохновленный Test, если команда выводит пустую строку, которую я придумал: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
источник
docker ps -aq ...
. Эта-a
опция означает, что он также найдет контейнеры, которые существуют, но в настоящее время не работают.ps -aq
, как предлагает @PeterBloomfield.grep -q .
также имеет ненулевой существующий код и, следовательно, всю вашу строку. Так что это все равно приводит к ошибке. Что заставило бы меня добавить|| echo 'not found'
или что-то в этом роде. И здесь нет большой разницы с принятым ответомif docker ps -q --filter "name=rabbitmq" | grep -q .; then docker stop rabbitmq && docker rm -fv rabbitmq; fi
Уже давно пользуюсь докером. Это мой предпочтительный способ остановки и удаления контейнера докеров. Принцип истины нужен для того, чтобы всегда обеспечивать успех. Без него все сценарии bash завершились бы и выдали ошибку, если бы имя контейнера не существовало.
docker rm -f container_name || true
источник
docker rm -f container_name &>/dev/null && echo 'Removed old container'
Вы можете использовать:
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
команда получаетapp
переменную командной строки из переменной BASH$app
NR>1
пропускает первую строку заголовка изdocker ps
команды.$(NF) == app
Сравнить последний столбецNAMES
равен переменной приложения или нетисточник
# Stop and remove containers with names like "rabbitmq" and "rabbitmq123" if they exist CONTAINER_NAME="rabbitmq" OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")" if [ -n "$OLD" ]; then docker stop $OLD && docker rm $OLD fi
источник
Я предлагаю это заклинание в bash:
( docker stop $CONTAINER > /dev/null && echo Stopped container $CONTAINER && \ docker rm $CONTAINER ) 2>/dev/null || true
Он всегда завершается с 0, не жалуется, если контейнер не запущен, и печатает,
Stopped container $CONTAINER
если он действительно остановился.источник
stop
/rm
контейнер, если он найден.Общая форма, основанная на некоторых ответах здесь:
docker rm -f container_name > /dev/null 2>&1 && echo 'removed container' || echo 'nothing to remove'
источник
Скопируйте этот код в свой 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
источник
Если вы не удалите остановленные контейнеры, другой простой способ решить эту проблему - положиться на него
docker ps -a
, который всегда будет возвращать этот идентификатор контейнера. Затем выполнениеdocker stop
в этом остановленном контейнере идемпотентно просто ничего не сделает:docker stop $(docker ps -a --filter name= rabbitmq -q )
источник
чтобы сначала остановить все контейнеры, вы должны остановить все контейнеры с помощью
docker kill $(docker ps -q)
и удалить все контейнеры
и если вы хотите удалить все изображения, это команда
источник