如何移除旧的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个回答

23
这是我的docker-cleanup脚本,用于删除未标记的容器和镜像。请查看源代码获取更新内容。
#!/bin/sh
# Cleanup docker files: untagged containers and images.
#
# Use `docker-cleanup -n` for a dry run to see what would be deleted.

untagged_containers() {
  # Print containers using untagged images: $1 is used with awk's print: 0=line, 1=column 1.
  docker ps -a | awk '$2 ~ "[0-9a-f]{12}" {print $'$1'}'
}

untagged_images() {
  # Print untagged images: $1 is used with awk's print: 0=line, 3=column 3.
  # NOTE: intermediate images (via -a) seem to only cause
  # "Error: Conflict, foobarid wasn't deleted" messages.
  # Might be useful sometimes when Docker messed things up?!
  # docker images -a | awk '$1 == "<none>" {print $'$1'}'
  docker images | tail -n +2 | awk '$1 == "<none>" {print $'$1'}'
}

# Dry-run.
if [ "$1" = "-n" ]; then
  echo "=== Containers with uncommitted images: ==="
  untagged_containers 0
  echo

  echo "=== Uncommitted images: ==="
  untagged_images 0

  exit
fi

# Remove containers with untagged images.
echo "Removing containers:" >&2
untagged_containers 1 | xargs --no-run-if-empty docker rm --volumes=true

# Remove untagged images
echo "Removing images:" >&2
untagged_images 3 | xargs --no-run-if-empty docker rmi

来源: https://github.com/blueyed/dotfiles/blob/master/usr/bin/docker-cleanup

该链接指向blueyed的dotfiles仓库中的docker-cleanup文件。

@BradMurray 谢谢!你可能也会喜欢这些:https://github.com/blueyed/dotfiles/commit/12591ec823d408997819b354c7dc4ac3dfeb88eb - blueyed
3
因为xargs --no-run-if-empty选项的缘故,此方法在OSX上不可行。 - caktux

15

首先,在尝试删除容器之前停止运行的容器

删除正在运行的容器

docker rm $(docker stop -t=1 $(docker ps -q))

你可以使用kill代替stop。在我的情况下,我更喜欢使用stop,因为我倾向于重新运行它们而不是每次创建一个新的容器,所以我试图优雅地关闭它们。 注意: 尝试停止一个容器将会给你一个错误:

错误: 无法删除正在运行的容器,请先停止它

删除所有容器

docker rm $(docker ps -a -q)

12

移除Windows shell中的所有容器:

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

我会在我的答案中包含这个,因为那是第一页。谢谢。 - qkrijger
“from Windows shell”?你是指“使用Windows shell(CMD)吗?” - Peter Mortensen

11

https://github.com/HardySimpson/docker-cleanup

Docker清理工具

一个小巧的全能shell脚本,可以移除:

  • 超过一天未运行的容器
  • 不属于任何剩余容器的镜像

可以作为cron任务运行。

功能特点

  • 将删除所有<none>:<none>镜像
  • 如果镜像有多个repo:tag引用,则除正在运行的容器外,将删除所有repo:tag。实际上这是“docker rmi”的本质。
  • 会在屏幕上显示许多错误消息,您可以决定是否使用2>/dev/null
  • 从docker-gc中学习,并解决其问题(无法删除具有多个repo:tag的镜像)

10

因此,个人建议将此作为部署脚本的一部分来完成,包括镜像和容器,仅保留最近的 n 个容器和镜像。我使用与 git tag 相同的版本控制模式对我的 Docker 镜像进行标记,并始终使用 "latest" 标记最新的 Docker 镜像。这意味着,即使不清理任何内容,我的 Docker 镜像看起来也是这样的:

REPOSITORY              TAG       IMAGE ID        CREATED         VIRTUAL SIZE
some_repo/some_image    0.0.5     8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    latest    8f1a7c7ba93c    23 hours ago    925.4 MB
some_repo/some_image    0.0.4     0beabfa514ea    45 hours ago    925.4 MB
some_repo/some_image    0.0.3     54302cd10bf2    6 days ago      978.5 MB
some_repo/some_image    0.0.2     0078b30f3d9a    7 days ago      978.5 MB
some_repo/some_image    0.0.1     sdfgdf0f3d9a    8 days ago      938.5 MB

当然,我不想在所有的生产服务器上永久保存所有的镜像(或者容器)。我只想保留最近的3到4个版本以备回滚,并且删除其余的版本。Unix中的tail命令可以帮助我们实现这个功能。由于docker imagesdocker ps命令都按照时间排序,因此我们可以使用tail命令来选择排名倒数前三的镜像或容器并将其删除:

docker rmi $(docker images -q | tail -n +4)

将此与您的部署脚本(或本地)一起运行,以始终保留足够的图像,以便在回滚时不会占用太多空间或使旧图像混乱。

个人而言,我在我的生产服务器上只保留一个容器,但如果需要更多容器,则可以执行类似的操作:

docker rm $(docker ps -aq | tail -n +4)

最后,在我的简化示例中,我们一次只处理一个存储库,但如果您有更多存储库,您可以使用同样的思路变得更加复杂。假设我只想保留来自some_repo/some_image的最后三个映像。我只需混合使用grepawk即可轻松完成:

docker rmi $(docker images -a | grep 'some_repo/some_image' | awk '{print $3}' | tail -n +4)

同样的想法也适用于容器,但是你已经理解了,所以我不会再举例子了。


9

查看所有现有的图片:

docker images -a

查看所有现有的容器:

docker ps -a

删除单个图像:

docker images -a
docker rmi <IMAGE_ID>

停止单个容器:

docker ps -a
docker stop <CONTAINER_ID>

停止多个容器:

docker ps -a
docker stop <CONTAINER_ID1> <CONTAINER_ID2>

删除单个容器:

docker ps -a
docker rm <CONTAINER_ID>

批量删除图片:

docker images -a
docker rmi <IMAGE_ID1> <IMAGE_ID2>

批量删除已停止的容器:

docker ps -a
docker rm <CONTAINER_ID1> <CONTAINER_ID2>

仅需一个命令删除图像:

docker rmi -f $(docker images -a -q)

一条指令中删除两个容器和镜像:

docker rm $(docker ps -a -q) && docker rmi -f $(docker images -a -q)

剪枝所有容器:

docker container prune

docker rm $(docker ps -a -q) || true && docker rmi -f $(docker images -a -q),通过添加 || true,即使没有容器需要删除,您也可以继续删除镜像。 - machin

8

使用:

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

此命令会强制停止并删除所有本地存在的容器。


请编辑并提供更多信息。仅包含代码和“尝试此”答案将被限制,因为它们不包含可搜索的内容,也没有解释为什么某人应该“尝试此”。我们在这里努力成为一个知识资源。 - Brian Tompsett - 汤莱恩
在Ubuntu 16.04中,Docker需要使用sudo,因此您必须编写sudo docker rm -f $(sudo docker ps -a -q) - Elliott
作为额外的好处,在PowerShell下,这也适用于Windows! - Robert Ivanc
@Elliott 我认为无论何时都需要使用 sudo,除非你将自己的用户添加到“docker”组中。我在Ubuntu 16.10上通过将我的用户添加到docker组来避免使用sudo。 - emory

7

移除最老的5个容器:

docker rm `docker ps -aq | tail -n 5`

查看剩余的容器数量:

docker ps -aq | wc -l

干得好,@Pithikos。我已经添加了一个答案,可以删除所有旧容器。 - Mostafa Ghadimi

7

删除所有已停止的容器。

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

此命令将通过获取所有容器的列表并使用其 ID 作为参数传递给 docker rm 命令,从而删除所有已停止的容器。这不会删除任何正在运行的容器,并且如果有运行的容器,则会提示无法删除它们。

删除所有未标记的镜像

现在,您需要清理旧的镜像以节省空间。

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


不要忘记通过指定 -v 选项来删除 Docker 卷 (sudo docker rm -v $(sudo docker ps -a -q))。 - vcarel
没有查过,但我猜应该和这个命令一样:docker ps -aq | xargs docker rm -v - quine
这只适用于Linux,而不是Windows...但是docker rm -f $(docker ps -a -q)在PowerShell / Docker for Windows中可以使用。 - Peter Mortensen

6

新方法:使用spotify/docker-gc来解决问题。

 docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc spotify/docker-gc
  • 超过一小时未运行的容器将被删除。
  • 在此之后,不属于任何剩余容器的镜像将被删除。

它支持环境设置。

强制删除具有多个标签的镜像

 FORCE_IMAGE_REMOVAL=1

Forcing deletion of containers

 FORCE_CONTAINER_REMOVAL=1 

排除最近退出的容器和镜像不受垃圾回收影响

 GRACE_PERIOD_SECONDS=86400

该设置还防止删除在GRACE_PERIOD_SECONDS秒之内创建的图像。

模拟运行

 DRY_RUN=1

清理孤立的容器卷 CLEAN_UP_VOLUMES=1

参考: docker-gc

旧的操作方式:

删除旧的、非运行中的容器

 docker ps -a -q -f status=exited | xargs --no-run-if-empty docker rm
             OR 
 docker rm $(docker ps -a -q)

删除所有与非运行的Docker容器相关联的镜像

 docker images -q | xargs --no-run-if-empty docker rmi

清理孤立的Docker卷(适用于Docker版本1.10.x及以上)
 docker volume ls -qf dangling=true | xargs -r docker volume rm

按时间段分类

 docker ps -a | grep "weeks ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "days ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm
 docker ps -a | grep "hours ago" | awk "{print $1}" | xargs --no-run-if-empty docker rm

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