如何移除旧的Docker容器

1455
这个问题涉及到是否应该担心不需要的未运行 Docker 容器?
我想知道如何删除旧的容器。使用docker rm 3e552code34a可以删除一个容器,但是我已经有很多了。docker rm --help没有提供选择选项(例如全部或按镜像名称)。
也许有一个目录存储这些容器,我可以手动轻松删除它们吗?

23
你也应该考虑清理孤立的Docker数据卷。我经常发现它们占用的空间比旧容器和旧镜像还要多。一个好的脚本可以帮助你删除这些孤立的Docker数据卷,你可以从这里获取:https://github.com/chadoe/docker-cleanup-volumes。 - Nemanja Trifunovic
也许 https://github.com/chadoe/docker-cleanup-volumes 可以帮助你。 - Mihai8
14
在Docker 1.13(2016年第四季度)中,您还可以考虑使用新的docker system prune命令。请参见我的下面的回答 - VonC
@VonC 这在我的 Docker version 1.12.3, build 6b644ec 上没有用 :) - ReynierPM
1
使用Docker管理工具Portainer我们可以使用这个工具来管理所有旧的容器、未使用的卷和镜像它是一个简单的Docker管理UI请参考下面我的更新,了解如何部署应用程序 - Anish Varghese
显示剩余2条评论
67个回答

1774

自从Docker 1.13.x版本起,您可以使用Docker container prune来清理 Docker 容器:

docker container prune

这将删除所有已停止的容器,并且在所有平台上的效果相同。

还有一个Docker system prune命令:

docker system prune

该命令将清理所有未使用的容器、网络、镜像(包括悬空和未引用的),并可选择清理卷。


对于旧版本的Docker,可以将Docker命令与其他Unix命令串联起来以获得所需结果。以下是一个示例,演示如何清理多周前的旧容器:

$ docker ps --filter "status=exited" | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm

为了给应该得到的荣誉,这个例子来源于https://twitter.com/jpetazzo/status/347431091415703552


100
删除所有未标记镜像的类似命令:docker images | grep "<none>" | awk '{print $3}' | xargs docker rmi (翻译说明:该命令用于Docker容器中删除所有未被打上标签的镜像。) - Mohan Raj
7
在使用 Dockerfile 构建镜像时,你可以指定 -rm 选项,在构建成功后删除中间容器。 - Freek Kalter
4
@MichelMüller 这些图像是用于缓存的,因此删除容器不会影响它们。 - Ken Cochrane
8
如果您想要使用 awk 命令做这件事,请考虑以下命令:如果您想要删除所有已停止的容器而不出现错误提示,请使用以下命令:docker ps -a | awk 'NR > 1 {print $1}' | xargs docker rm。请注意,此命令是用于 Docker 环境的。 - omni
4
这应该是删除未标记镜像的更新命令: docker rmi $(docker images -q -f dangling=true) - Ghjnut
显示剩余17条评论

652

另一种方法,我从Guillaume J. Charmes那里得到的(功劳归于他):

docker rm `docker ps --no-trunc -aq`

将以优雅的方式删除所有容器。

而Bartosz Bilicki为Windows编写:

FOR /f "tokens=*" %i IN ('docker ps -a -q') DO docker rm %i

对于PowerShell:

docker rm @(docker ps -aq)

在 Docker 1.13(2016年第四季度)中进行了更新,感谢VonC本帖的后续回答):

docker system prune 将删除所有未使用的数据(即:已停止的容器、没有容器的卷以及没有容器的映像)。

请参见 PR 26108commit 86de7c0,它们引入了一些新命令,可以帮助可视化 Docker 守护程序数据占用磁盘的空间大小,并轻松清理“不必要”的多余内容。

docker system prune

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y

11
对我来说这似乎不起作用,但是docker ps -a -q | xargs docker rm有效(可能需要sudo)。 - FUD
88
docker rm $(docker ps -a -q) 的意思是什么? - qkrijger
9
@qkrijger,除了添加了bashism外,这并没有改变您原来的答案。问题在于命令行溢出。 xargs 变体以一种不错的方式处理它。我还会在 docker ps 中添加 --no-trunk 以避免(不太可能的)ID 冲突。 - Ihor Kaharlichenko
9
请注意,如果您使用的是仅数据容器,它也会将它们删除。 - Dzung Nguyen
4
我对使用 --no-trunc 没有任何意义,因为无论如何 docker rm 都不需要完整的容器 ID。 - Pithikos
显示剩余15条评论

425

更新的答案 现在使用docker system prunedocker container prune。请参见VonC更新后的答案

旧答案 综合上面的几个提示,最优雅的删除所有非运行容器的方法似乎是:

docker rm $(docker ps -q -f status=exited)

  • -q仅打印容器ID(不包括列标题)
  • -f允许您过滤打印的容器列表(在这种情况下,我们正在过滤仅显示已退出的容器)

7
这应该是正确答案,因为它依赖 Docker 来告诉你哪些容器不再使用,而不是假设 $(docker images) 的文本输出格式不会改变。额外加分的是只产生一个额外进程而不是两个。 - Ch4ni
20
你可能需要添加-v以避免悬挂卷:docker rm -v $(docker ps -q -f status=exited)。有关悬挂卷的详细信息,请参见https://docs.docker.com/userguide/dockervolumes/#creating-and-mounting-a-data-volume-container。 - rluba
@rluba 显然在 Docker 1.9 中将会有一个单独的卷 API 来处理这个问题。https://github.com/docker/docker/pull/14242 - Ryan Walls
一个别名可能很方便: alias docker-gc="docker rm -v \$(docker ps -q -f status=exited)" - Frank Neblung
与标记为正确的答案不同,@RyanWalls的答案在OSX上也能工作,并且更加简洁。 - Ray
"docker rm" 需要至少 1 个参数。 - Xero

261

官方的方法是:链接

docker rm `docker ps -aq`

Docker维护人员已经表示不会为此提供命令 - 而是像这样组合命令:

我们之前已经讨论过并且更喜欢用户使用上面的命令行,而不必向Docker添加额外的代码。


7
不过,这是一个糟糕的解决方案,因为它还将删除存储容器。 - Sobrique
9
你说的“存储容器”是什么意思?如果你指的是仅用于保留数据卷引用的数据容器,那么现在已经不再需要了,因为有了docker volume子命令和命名卷。 - L0j1k
请注意,这在Windows Powershell中不起作用。对此,有更好的解决方案:https://dev59.com/DGQm5IYBdhLWcg3w6ShR#23674294 - Bram Vanroy
@Sobrique 如果你不回应,至少也应该删除你的评论,因为它几乎是完全无意义和有害的。 - peterh

132
使用Docker 1.13(2016年第四季度),您现在可以: docker system prune -a将删除所有未使用的数据(即:停止的容器、没有容器的卷和没有容器的镜像)。 docker system prune不带-a参数只会删除(对于镜像)悬空的镜像,或者没有标签的镜像,如commented所述,由smilebomb提供。
请参考PR 26108commit 86de7c0,它们引入了一些新的命令,以帮助可视化Docker守护程序数据占用的磁盘空间,并方便地清理“不必要”的多余数据。
docker system prune -a

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N] y

根据wjv的评论,
还有docker {container,image,volume,network} prune,可以用来删除仅仅一种类型的未使用实例。
commit 913e5cb中引入,仅适用于Docker 1.13+。
docker container prune

2023年:Taiger评论中指出:

对于现代版本的Docker来说,正确的答案是:"清理未使用的Docker对象"


3
应该将其标记为现今正确的答案,大多数以上的答案在过去是正确的,但如今已变得过于复杂。 - Eugen Mayer
同意,最近容易多了,上升吧! - Maxim
代码块中的描述是针对 docker system prune -a 的,它可以删除未使用的镜像。而 docker system prune 只会删除 悬空 镜像,即没有标签的镜像。 - smilebomb
这是适用于现代版本的Docker的正确答案。 https://docs.docker.com/config/pruning/ - undefined
@Taiger 谢谢您的反馈。我已将您的评论包含在答案中,以增加其可见性。 - undefined
显示剩余5条评论

127

更新 2021年(最新)

docker container prune

这是 - 2017 (旧的) 方法

用于删除所有已停止的容器

docker rm $(docker ps -a -q)

删除 所有容器 (停止和非停止)

docker rm  -f $(docker ps -a -q)

5
由于这绝对不是2017年处理方式,因此已被downvote - 正确的做法应该是docker volume/container/image prune,请参见https://dev59.com/DGQm5IYBdhLWcg3w6ShR#39860665。 - Eugen Mayer
12
因为a) 这个回答是来自2016年的,b)有很多人不使用最新的技术,所以点赞来抵消踩。 - keen
在 Windows10 中,未知的速记标志:“a” 在“-a”中。 - GML-VS
我们可以使用过滤选项来简单地删除容器。注意:until=24h 表示 24 小时之前的容器,您可以根据需要进行更改。
docker container prune --filter "until=24h"
- Aniket J kamble

109

现在可以使用筛选功能来对 docker ps 进行操作:

docker rm $(docker ps -q -f status=exited)

对于镜像

docker rmi $(docker images -q -f "dangling=true")

然而,所有这些方法都会导致docker rmdocker rmi在没有匹配的容器时抛出错误。更古老的docker rm $(docker ps -aq)技巧还更糟糕,因为它试图删除任何正在运行的容器,并在删除每个容器时失败。

以下是一个更清晰的脚本,可添加到您的~/.bashrc~/.profile

# Use `docker-cleanup --dry-run` to see what would be deleted.

function docker-cleanup {
  EXITED=$(docker ps -q -f status=exited)
  DANGLING=$(docker images -q -f "dangling=true")

  if [ "$1" == "--dry-run" ]; then
    echo "==> Would stop containers:"
    echo $EXITED
    echo "==> And images:"
    echo $DANGLING
  else
    if [ -n "$EXITED" ]; then
      docker rm $EXITED
    else
      echo "No containers to remove."
    fi
    if [ -n "$DANGLING" ]; then
      docker rmi $DANGLING
    else
      echo "No images to remove."
    fi
  fi
}

编辑:如下注所述,原始回答是针对去除图片而非容器。已更新以回答两者,并包含新的文档链接。感谢Adrian(以及Ryan的回答)提到了新的ps过滤器。


2
请注意这个的真正优势 - 您不会意外删除 storage 容器。 - Sobrique
3
你也可以使用 status=created 来获取那些未运行过且从未运行过的任务。 - enderland

50

删除所有已停止的容器:

docker rm $(docker ps -a | grep Exited | awk '{print $1}')

根据 pauk960 的评论:

从版本1.3.0开始,您可以在docker ps中使用过滤器,而不是使用grep Exited,请使用docker ps -a -f status=exited。如果您与其一起使用-q,则只能获取容器ID,而无需使用awk获取完整输出。


38

如果您不想删除所有容器,您可以使用 docker ps -f before=<container-ID>docker ps -f since=<container-ID> 选择在特定容器之前或之后创建的所有容器。

假设您已经开发出系统并让它运行起来,但是还剩下一些容器。您希望删除在该工作版本之前创建的容器。使用 docker ps 确定正在运行的容器的ID。

删除在另一个容器之前创建的容器

docker rm $(docker ps -f before=9c49c11c8d21 -q)

另一个例子。您的数据库已在Docker容器上运行。您已经开发好了在另一个容器上运行的应用程序,现在您有许多不需要的容器。

删除在某个容器之后创建的容器

docker rm $(docker ps -f since=a6ca4661ec7f -q)

Docker在Ubuntu中将容器存储在/var/lib/docker/containers中。我认为多余的容器不会造成其他影响,但会占据磁盘空间。


33

更新:从 Docker 1.13 版本起(发布于2017年1月),您可以执行以下命令清理已停止的容器、未使用的卷、悬空镜像和未使用的网络:

docker system prune
如果你想确保只删除那些具有 "已停止" 状态的容器,可以使用以下命令: docker rm $(docker ps -a -f status=exited -q)
docker ps -aq -f status=exited | xargs docker rm

同样,如果你正在清理Docker相关内容,你可以通过以下方式摆脱未打标签、无名称的镜像:

docker images -q --no-trunc -f dangling=true | xargs docker rmi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接