在长时间运行Docker时,系统中存在大量的镜像。如何一次安全地删除所有未使用的Docker映像以释放存储空间?
另外,我还想删除几个月前拉的图片,这些图片有正确的TAG。
因此,我并不是只要求删除未标记的图像。我正在寻找一种方法来删除一般不使用的图像,其中包括未标记和其他图像,如几个月前拉正确的TAG。
在长时间运行Docker时,系统中存在大量的镜像。如何一次安全地删除所有未使用的Docker映像以释放存储空间?
另外,我还想删除几个月前拉的图片,这些图片有正确的TAG。
因此,我并不是只要求删除未标记的图像。我正在寻找一种方法来删除一般不使用的图像,其中包括未标记和其他图像,如几个月前拉正确的TAG。
当前回答
请参阅docker系统修剪的官方参考
Docker系统修剪将删除:
所有停止的集装箱 所有网络不被至少一个容器使用 所有悬挂的图像 所有构建缓存
Docker系统prune -a也会做同样的事情,但是除了删除所有悬浮图像之外,它还会更广泛地删除:
没有至少一个与之关联的容器的所有映像
什么是悬空图像?
Docker映像由多个层组成,当从Dockerfile生成整个容器映像时,这些层被包装在父“容器层”中。悬浮图像是与任何其他标记图像没有关系的层,因此在任何构建的新容器中都不会有任何用途。它们不再起作用,而是消耗磁盘空间。
例如,悬浮图像可以通过以下过程创建:
从Dockerfile中构建一个命名image my-image,不指定任何标签:
FROM ubuntu:latest
CMD ["echo", "Hello World"]
docker build -t my-image
docker images
REPOSITORY TAG IMAGE ID
my-image latest 7ed6e7202eca <--- created, not dangling
ubuntu latest 825d55fb6340
更新Dockerfile:
FROM ubuntu:latest
CMD ["echo", "Hello, World!"]
使用以前的名称重新构建映像,不指定任何标记:
docker build -t my-image
docker images
REPOSITORY TAG IMAGE ID
my-image latest da6e74196f66 <--- replacement layer
<none> <none> 7ed6e7202eca <--- previous layer, now dangling
ubuntu latest 825d55fb6340
构建创建了一个新的my-image层。正如我们所看到的,最初创建的层仍然在那里,但它的名称和标签被设置为<none>:<none>。这个层永远不可能与任何docker容器层相关联,这意味着它是“悬空的”。
没有至少一个关联容器的图像是什么?
未使用的映像意味着它没有被分配或在容器中使用。例如,docker ps -a将列出所有运行和停止的容器。这些容器使用的任何映像都是“已用映像”。
当运行docker系统prune -a时,它将删除未使用和悬挂的图像。与至少一个容器相关联的任何映像都不会受到影响。
其他回答
第二次更新(2017-07-08)
参考(再次)VonC,使用更近期的系统修剪。不耐烦的人可以使用-f,——force选项跳过提示符:
docker system prune -f
没有耐心和鲁莽的人还可以使用-a,——all选项删除“未使用的图像,而不仅仅是悬垂的图像”:
docker system prune -af
https://docs.docker.com/engine/reference/commandline/system_prune/
更新
参考VonC的答案,它使用了最近添加的修剪命令。下面是对应的shell别名方便:
alias docker-clean=' \
docker container prune -f ; \
docker image prune -f ; \
docker network prune -f ; \
docker volume prune -f '
旧的答案
删除停止(退出)的容器:
$ docker ps --no-trunc -aqf "status=exited" | xargs docker rm
删除未使用的(悬空的)图像:
$ docker images --no-trunc -aqf "dangling=true" | xargs docker rmi
如果您对不可撤销的数据丢失非常谨慎,那么您可以删除未使用的(悬空)卷(v1.9及以上版本):
$ docker volume ls -qf "dangling=true" | xargs docker volume rm
下面是一个方便的shell别名:
alias docker-clean=' \
docker ps --no-trunc -aqf "status=exited" | xargs docker rm ; \
docker images --no-trunc -aqf "dangling=true" | xargs docker rmi ; \
docker volume ls -qf "dangling=true" | xargs docker volume rm'
参考文献
Docker ps -f 码头工人rm Docker images -f 码头工人rmi Docker v1.9.0版本说明 Docker卷ls Docker卷rm
docker rm `docker ps -aq`
or
docker rm $(docker ps -q -f status=exited)
@VonC已经给出了一个非常好的答案,但为了完整起见,这里有一个我一直在使用的小脚本——如果你有一些差事,它也会破坏任何Docker进程:
#!/bin/bash
imgs=$(docker images | awk '/<none>/ { print $3 }')
if [ "${imgs}" != "" ]; then
echo docker rmi ${imgs}
docker rmi ${imgs}
else
echo "No images to remove"
fi
procs=$(docker ps -a -q --no-trunc)
if [ "${procs}" != "" ]; then
echo docker rm ${procs}
docker rm ${procs}
else
echo "No processes to purge"
fi
到目前为止(Docker版本1.12),我们使用以下命令删除所有正在运行的容器。同样,如果我们想要删除卷,我们可以在下面的命令中使用相应的标记-v手动删除卷。
删除所有退出的容器
docker rm $(docker ps -q -f status=exited)
删除所有停止的容器
docker rm $(docker ps -a -q)
删除所有运行和停止的容器
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
删除所有容器,没有任何标准
docker container rm $(docker container ps -aq)
但是,在1.13及以上版本中,为了完整的系统和清理,我们可以直接使用以下命令:
docker system prune
所有未使用的容器、映像、网络和卷都将被删除。我们也可以使用以下命令来清理单个组件:
docker container prune
docker image prune
docker network prune
docker volume prune
这招对我很管用:
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")