I want to clean up all of my Docker images that aren't being used, directly or indirectly, by my current containers. Docker provides the docker image prune command for this, but I can't get it to remove exactly what I want. If I use that command without -a, it removes too little: it leaves behind all tagged images, even if no container uses them. If I use that command with -a, it removes too much: it removes images that are parents of images that aren't being removed. Here's a table explaining the problem:
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
Run Code Online (Sandbox Code Playgroud)
Is there some other flag for this command (such as something with --filter), or some other command or sequence of commands, that lets me remove just what I want to remove?
EDIT: David Maze points out in the comments that the images I'm referring to are merely being untagged, not removed entirely. Given that, here's an updated phrasing of the question: How can I make docker image prune -a not untag images that it's not actually going to remove?
我经常想知道同样的事情,所以我想出了这个解决方案:
# 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
}
Run Code Online (Sandbox Code Playgroud)
不是很优雅,但它足以在开发中使用。您可以传递一个-y标志来消除警告提示。
我遇到过几种情况,提示错误地显示了当前使用的图像,并试图将其删除,但随后被 docker 守护进程捕获,从而导致类似于以下的误导性噪音:
Error response from daemon: conflict: unable to delete <image id> (must be forced) -
image is being used by stopped container <container id>
Run Code Online (Sandbox Code Playgroud)
在所有情况下,仅删除正确的图像,但这可能会因您的系统而异。青年MMV
太长了;不安全生产
| 归档时间: |
|
| 查看次数: |
402 次 |
| 最近记录: |