删除所有没有容器或子映像的Docker映像,即使它们已被标记

时间:2018-10-18 20:37:21

标签: docker

我想清除当前容器未直接或间接使用的所有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不取消标记实际上不会删除的图像?

3 个答案:

答案 0 :(得分:2)

我经常想知道同一件事,所以我想出了以下解决方案:

# 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>

在所有情况下,仅删除了正确图像,但这可能会因系统而异。 YMMV

TLDR;不安全生产

答案 1 :(得分:-1)

通常,当我不关心运行系统来清理空间时,会先清理所有下载的图像。

命令: await self.log( ctx, 'tdescription here', 'title here', discord.Color.blue(), fields=[ ('**Field**', "field value, you can add more fields") ], showauth=True ) # you can use message, title, color, field(s), and the showauth

在这里

docker rmi $(docker images -aq) -f将返回系统中所有可用图像的ID列表。

docker images -aq将强制删除图像,即使该图像已标记为容器。

答案 2 :(得分:-1)

docker image prune -a --filter "until=24h" 

这是我使用的东西,希望对您有所帮助。