Docker:停止并删除 docker 容器(如果它正在运行)

Posted

技术标签:

【中文标题】Docker:停止并删除 docker 容器(如果它正在运行)【英文标题】:Docker: Stop and delete docker container if it's running 【发布时间】:2016-03-17 16:20:14 【问题描述】:

如果 docker 容器正在运行,我希望务实地停止并删除它。这是一个构建脚本。

举个例子。如何停止和删除 bash 脚本中 NAMES 列下的 docker 容器“rabbitmq”?

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

【问题讨论】:

【参考方案1】:

你可以使用:

app="rabbitmq"
if docker ps | awk -v app="$app" 'NR > 1 && $NF == appret=1; exit ENDexit !ret'; then
  docker stop "$app" && docker rm -f "$app"
fi
awk 命令从 BASH 的变量 $app 中获取命令行变量 app NR>1 跳过 docker ps 命令的第一行。 $(NF) == app比较最后一列NAMES是否等于app变量

【讨论】:

您好,感谢您提供的答案。您能否稍微扩展一下它的作用。如果我有 app=''some-rabbitmq' 它不喜欢炒作? 它应该与连字符一起使用,我在回答中添加了一些解释。 解决方案太复杂了。第二个答案更好 这是最完整的答案。添加`||的问题true` 是它仍然存在一个带有 docker 错误的 bash 脚本。通过检查容器的 docker 容器列表,您可以保证仅在存在时调用 stop 和 rm,消除错误并允许脚本运行所需的所有容器命令。【参考方案2】:

您可能已经注意到,docker stopdocker rm 在容器不存在或未运行时退出并带有指示失败的状态代码。这会导致您的构建失败。

如果您可以处理构建日志中的错误消息,您可以使用这个小技巧来防止 shell 命令失败:

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

在 docker 命令之一失败的情况下,true 会被调用,它总是退出并显示成功的状态码。

【讨论】:

仍然返回容器不存在的错误信息,但状态码表示成功。我的竹管道过程没有失败,所以它对我有用。 这将在容器已经被移除时生成Error response from daemon: no such id: rabbitmq @anubhava:正确。正如答案中已经提到的:“诀窍”是忽略 docker 命令的返回值。如果您需要一个没有错误消息的“干净”解决方案,您需要检查容器是否存在。 对我来说,这个命令不再起作用了,它曾经起作用,但现在它不起作用了……这是否发生在其他人身上? 您可以使用--rm 运行容器,然后使用docker stop container_name || true 停止。它会自行移除。【参考方案3】:

我有类似的问题,但不喜欢接受的答案,因为它会抑制命令中的所有错误,而不仅仅是“未找到”错误。

但是,docker ps -q --filter "name=rabbitmq" 仅在该名称的容器实际存在时才会产生输出,因此受到Test if a command outputs an empty string 的启发,我想出了:

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 选项意味着它还将找到存在但当前未运行的容器。 很好的答案,我只是在 bash 脚本中使用了它,如果它已经在运行,让它重新启动 docker 容器。正如@PeterBloomfield 所建议的,也使用了ps -aq 如果找不到容器,grep -q . 也有一个非零存在代码,因此你的整个行。所以这仍然会导致错误。这将迫使我附加|| echo 'not found' 或类似的东西。到那时,接受的答案并没有太大区别 为避免过滤器影响整个命令返回码,您可以将其重构为 if 语句:if docker ps -q --filter "name=rabbitmq" | grep -q .; then docker stop rabbitmq && docker rm -fv rabbitmq; fi 我从 docker ps -qa --filter 开始,以确保任何崩溃的容器也能显示出来。【参考方案4】:

这是我停止和删除 docker 容器的首选方式。 true 的管道是为了确保它始终输出成功。没有它,如果容器名称不存在,任何 bash 脚本都会退出并出错。

docker rm -f container_name || true

【讨论】:

docker rm -f container_name &>/dev/null && echo 'Removed old container' docker container rm | Docker Documentation: 强制删除正在运行的容器(使用 SIGKILL) 您可以使用--rm 运行容器,然后使用docker stop container_name || true 停止。【参考方案5】:

要先停止所有容器,您必须使用

停止所有容器
docker kill $(docker ps -q)

并删除所有容器

docker rm $(docker ps -a -q)

如果你想删除所有图像,这是命令

docker rmi $(docker images -q)

【讨论】:

您不能在共享环境中执行此操作。图片您有两个正在运行的管道。【参考方案6】:
# 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

【讨论】:

【参考方案7】:

如果您想要 stopremove 全部,请将此代码复制到您的 script.sh 中

#!/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,它将始终返回该容器 ID。然后在该停止的容器上执行docker stop 将幂等地什么都不做:

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

【讨论】:

【参考方案9】:

我建议在 bash 中使用这个咒语:

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

它总是以 0 退出,如果容器没有运行,它不会抱怨,如果它真的停止了,它会打印 Stopped container $CONTAINER

【讨论】:

Clean tear down,如果没有找到容器,它会静默“失败”,但如果找到容器,则不会静默stop/rm容器。【参考方案10】:

这里基于一些答案的一般形式:

docker rm -f container_name > /dev/null 2>&1 && echo 'removed container' || echo 'nothing to remove'

【讨论】:

【参考方案11】:

解决这个问题的简单方法

docker container ls -al | grep <name> && docker container rm -f <name>

【讨论】:

【参考方案12】:

在以下场景中:-

    Windows 上的 Docker(wsl2) Jenkins 服务器在同一个窗口上。 使用 Jenkins 管道构建和运行容器。 在管道中使用 bat 脚本。

在这种情况下,您可以使用以下命令来防止构建失败。

'docker stop rabbitmq && docker rm rabbitmq || exit 0;'

【讨论】:

【参考方案13】:

在 CI/CD 管道或不需要输出的东西中,我使用的方式是这样的:

docker rm -f rabbitmq &> /dev/null

但据我所知,&amp;&gt; 不是官方 POSIX 规范的一部分,所以我们应该使用:

docker rm -f rabbitmq 1> /dev/null 2>&1

-f(强制)在docker rm -f

强制删除正在运行的容器(使用 SIGKILL)

而不是 docker stop 发送:

.. SIGTERM,在宽限期之后,SIGKILL

1&gt; /dev/nul 将输出 1 (stdout) 重定向到 /dev/null2&gt;&amp;1 将错误 2 (stderr) 重定向到相同的“文件”。 &amp; 作为第一个示例重定向 1 和 2。

要编写真实文件并附加内容,请使用docker rm -f rabbitmq 1&gt;&gt; docker_rabbitmq.txt 2&gt;&amp;1 或不同的文件docker rm -f rabbitmq 1&gt;&gt; docker_rabbitmq_success.txt 2&gt;&gt; docker_rabbitmq_error.txt

【讨论】:

【参考方案14】:

试试下面的功能。改编自https://***.com/a/60579344/1554778

    function remove_previous_instance()
        echo "Container name: $1"
        CNAME=$1
        if [ "$(docker ps -qa -f name=$CNAME)" ]; then
            echo ":: Found container - $CNAME"
            if [ "$(docker ps -q -f name=$CNAME)" ]; then
                echo ":: Stopping running container - $CNAME"
                docker stop $CNAME;
            fi
            echo ":: Removing stopped container - $CNAME"
            docker rm $CNAME;
        fi
    

调用它: remove_previous_instance "CNAME"

【讨论】:

以上是关于Docker:停止并删除 docker 容器(如果它正在运行)的主要内容,如果未能解决你的问题,请参考以下文章

sh 停止并删除所有docker容器

删除所有的docker容器和镜像

Docker Review - docker 容器 常用命令

Docker容器使用

docker 停止&删除命令

docker 常用命令整理