在长时间运行Docker时,系统中存在大量的镜像。如何一次安全地删除所有未使用的Docker映像以释放存储空间?

另外,我还想删除几个月前拉的图片,这些图片有正确的TAG。

因此,我并不是只要求删除未标记的图像。我正在寻找一种方法来删除一般不使用的图像,其中包括未标记和其他图像,如几个月前拉正确的TAG。


当前回答

要修剪所有的图像和卷以及 Docker系统剪枝-af——volumes

其他回答

(原答案见下文)


2016年9月更新:Docker 1.13: PR 26108和commit 86de7c0引入了一些新命令,以帮助方便地可视化Docker守护进程数据在磁盘上占用了多少空间,并允许轻松清理“不需要的”多余空间。

docker系统修剪将删除所有悬空数据(即:容器停止,卷没有容器和图像没有容器)。即使是未使用的数据,使用-a选项。

你还有:

码头集装箱修剪 Docker映像修剪 Docker网络修剪 码头卷修剪

对于未使用的图像,使用docker image prune -a(用于删除悬空和未使用的图像)。 警告:'unused'表示“未被任何容器引用的图像”:在使用-a之前要小心。

正如A L的回答所示,docker系统prune -all将删除所有未使用的图像,而不仅仅是悬垂的图像…这可能有点太多了。

结合docker xxx prune和——filter选项可以是限制修剪的好方法(docker SDK API最低1.28,所以docker 17.04+)

目前支持的过滤器有:

Until (<timestamp>) -只删除在给定时间戳之前创建的容器、图像和网络 Label (Label =<key>, Label =<key>=<value>, Label !)=<key>, or label!=<key>=<value>) -仅删除带有(或没有,以防标签!=…使用)指定的标签。

有关示例,请参见“修剪图像”。


警告:docker xxx prune命令没有“预览”或“——dry-run”选项。

自2017年以来,moby/moby issue 30623要求这样做,但似乎很难实施(2022年8月)

Having a more representative overview of what will be pruned will be quite complicated, for various reasons; race conditions (can be resolved by documenting the limitations); A container/image/volume/network may not be in use at the time that "dry run" is used, but may be in use the moment the actual prune is executed (or vice-versa), so dry run will always be an "approximation" of what will be pruned. the more difficult part is due to how objects (containers, images, networks etc.) depend on each other. For example, an image can be deleted if it no longer has references to it (no more tags, no more containers using it); this is the reason that docker system prune deletes objects in a specific order (first remove all unused containers, then remove unused images). In order to replicate the same flow for "dry-run", it will be needed to temporarily construct representation of all objects and where they're referenced based on that (basically; duplicate all reference-counters, and then remove references from that "shadow" representation). Finally; with the work being done on integrating the containerd snapshotter (image and layer store), things may change more; For example, images can now be multi-arch, and (to be discussed), "pruning" could remove unused variants (architectures) from an image to clean up space, which brings another dimension to calculating "what can be removed".


原答案(2016年9月)

我通常这样做:

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

我有一个[别名删除这些悬空图像:drmi]13

悬空=true过滤器发现未使用的图像

这样,任何不再被标记图像引用的中间图像都将被删除。

我首先对退出的进程(容器)执行相同的操作

alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'

haridsv在评论中指出:

从技术上讲,在清理图像之前应该先清理容器,因为这样可以捕获更多悬空图像并减少错误。


Jess Frazelle (jfrazelle)有bashrc函数:

dcleanup(){
    docker rm -v $(docker ps --filter status=exited -q 2>/dev/null) 2>/dev/null
    docker rmi $(docker images --filter dangling=true -q 2>/dev/null) 2>/dev/null
}

要删除旧图像,而不仅仅是“未引用的悬空”图像,你可以考虑docker-gc:


一个简单的Docker容器和图像垃圾收集脚本。 超过一小时前离开的集装箱被移除。 删除之后不属于任何剩余容器的图像。

首先,运行docker images查看图像列表,并将IMAGE HASH ID复制到剪贴板中。

运行docker rmi -f <镜像>

记住选项-f是强制删除。

要删除超过一个月的旧标记图像:

$ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
    | grep ' months' | awk '{ print $1 }' \
    | xargs --no-run-if-empty docker rmi

注意,它将无法删除容器使用的图像,在存储库中引用,有依赖的子图像…这可能是你想要的。否则只需添加-f标志。

/etc/cron.示例每日/ docker-gc脚本:

#!/bin/sh -e

# Delete all stopped containers (including data-only containers).
docker ps -a -q --no-trunc --filter "status=exited" | xargs --no-run-if-empty docker rm -v

# Delete all tagged images more than a month old
# (will fail to remove images still used).
docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' | grep ' months' | awk '{ print $1 }' | xargs --no-run-if-empty docker rmi || true

# Delete all 'untagged/dangling' (<none>) images
# Those are used for Docker caching mechanism.
docker images -q --no-trunc --filter dangling=true | xargs --no-run-if-empty docker rmi

# Delete all dangling volumes.
docker volume ls -qf dangling=true | xargs --no-run-if-empty docker volume rm

其他答案都很棒,具体来说:

docker system prune # doesn't clean out old images
docker system prune --all # cleans out too much

但我需要在两个命令中间的一些东西,所以过滤器选项是我所需要的:

docker image prune --all --filter "until=4320h" # delete images older than 6 months ago; 4320h = 24 hour/day * 30 days/month * 6 months

参考:https://docs.docker.com/config/pruning/#prune-images

下面的命令将帮助从本地存储库中删除所有未使用的和旧的映像 ==> docker系统剪枝——全部