我想清理当前容器未直接或间接使用的所有 Docker 镜像。 Docker 提供了 docker image prune
命令,但我无法让它完全删除我想要的东西。如果我在没有 -a
的情况下使用该命令,它删除的太少:它会留下所有标记的图像,即使没有容器使用它们。如果我将该命令与 -a
一起使用,它删除了太多:它删除了未删除的图像的父图像。这是一个解释问题的表格:
Used by container | Has child image | Has tag | Removed without -a | Removed with -a | I want to remove
Yes | Yes/No | Yes/No | No | No | No
No | Yes | Yes/No | No | Yes | No
No | No | Yes | No | Yes | Yes
No | No | No | Yes | Yes | Yes
此命令是否有其他标志(例如带有
--filter
的标志)或其他一些命令或命令序列,可以让我删除我想要删除的内容?编辑 :David Maze在评论中指出我所指的图像只是未标记,并未完全删除。鉴于此,这里是问题的更新措辞:我如何制作
docker image prune -a
不取消标记它实际上不会删除的图像?
最佳答案
我经常想同样的事情,所以我想出了这个解决方案:
# create unique array of image ids (including all descendants) used by running containers
get_active_image_history()
{
for image_name in $(docker ps --format={{.Image}})
do
docker history -q $image_name
done | sort -u
}
# iterate over each image id in your system, and output the ids that should be deleted
# conceptually similar to an intersection of two arrays
get_unused_image_ids()
{
image_history=$(get_active_image_history)
for image_id in $(docker image ls -q)
do
if [[ ! "${image_history[@]}" =~ "${image_id}" ]]; then
echo "$image_id"
fi
done | sort -u
}
docker_clean()
{
image_ids=$(get_unused_image_ids)
if [ -z "$image_ids" ]; then
>&2 echo "Error: no unused images found"
return 1
fi
if [[ "$1" = "-y" ]]; then
echo y | docker container prune > /dev/null
docker image rm $(get_unused_image_ids)
return 0
fi
echo -e "Warning! this will remove all stopped containers, and the following images:\n"
image_ids=$(get_unused_image_ids)
echo "REPOSITORY TAG IMAGE ID CREATED SIZE"
docker image ls | grep "$image_ids"
echo
read -p "Continue (y/n)?" cont
if [ "$cont" = "y" ]; then
echo y | docker container prune > /dev/null
docker image rm $image_ids
else
echo "aborting..."
fi
}
不是很优雅,但它在开发中运行良好。您可以通过 -y
标志使警告提示静音。我遇到过几种情况,提示错误地显示了当前正在使用的图像,并试图将其删除,但随后被捕获
docker 守护进程会导致类似以下的误导性噪音:
Error response from daemon: conflict: unable to delete <image id> (must be forced) -
image is being used by stopped container <container id>
在所有情况下,只删除了正确的图像,但这可能因您的系统而异。青年会TLDR;不安全生产
关于docker - 删除所有没有容器或子镜像的 Docker 镜像,即使它们被标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52882184/