如何删除旧的和未使用的Docker镜像

How to remove old and unused Docker images

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

此外,我还想删除几个月前提取的具有正确TAG的图像。

所以,我不要求只删除未标记的图像。我正在寻找一种删除一般未使用的图像的方法,其中包括未标记的图像和其他图像,例如几个月前用正确的TAG提取的图像。


Update Seven.2016:docker 1.13:PR 26108 and commit 86de7c0 introduce a few new commands to help facilitate visualizing how much space the docker daemon data is taking on disk and allowing for easily cleaning up"unneed"excess.

Will delete all dangling data(I.E.in order:containers stopped,volumes without containers and images with no containers).即使未使用数据,与-a选项。

你也有:

  • docker container prune
  • 法国电力公司
  • docker network prune
  • 法国电力公司

对于未使用的图像,使用EDOCX1&6警告:未曾使用过"任何集装箱不参考的图像":在使用-a之前要小心。

作为答案中的说明,docker system prune --allWill remove a l l unused images not just dangling ones…这是一个太多的比特。

--filter相结合,这是一个很好的选择,可以限制李子(码头工人SDK API 1.28 minimum,so docker 17.04+)

The currently supported filters are:

  • 只有清除集装箱、图像和网络在给出时间之前创建
  • 只有清除集装箱、图像、网络和卷(或无需,以label!=...为例)才使用特殊标签。

See"Prune images"for an example.

原始答案

我经常做

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

我有一个别名来清除那些[Dangling图像]13:drmi

BLCK1/

这样,任何中间图像都不会被标记图像所引用。

我也做同样的第一个流程(集装箱)

ZZU1

As haridsv points out in the comments:

Technically, you should first clean up containers before cleaning up images, as this will catch more dangling images and less errors.

Jess Frazelle(Jfrazelle)has the Bashrc Function:

1
2
3
4
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
}

要清除旧的图像,而不只是"无参考-Dangling"图像,你可以考虑docker-gc

A simple Docker container and image garbage collection script.

  • Containers that exited more than an hour ago are removed.
  • Images that don't belong to any remaining container after that are removed.


更新第二期(2017-07-08年):

Refer(again)to vonc,using the even more recent system prune急躁的人可以用EDOCX1&21的方式来抓住快感:

1
docker system prune -f

The insext and reckless can additionally remove"unused images not just the dangling ones"with the -a, --alloption:

1
docker system prune -af

HTTPS://docs.docker.com/engine/reference/commandline/system&uprune/

更新:

Refer to vonc's answer which uses the recently added prune这里是通信壳牌外号

1
2
3
4
5
alias docker-clean=' \
  docker container prune -f ; \
  docker image prune -f ; \
  docker network prune -f ; \
  docker volume prune -f '

老答案:

删除(出口)集装箱:

1
$ docker ps --no-trunc -aqf"status=exited" | xargs docker rm

Delete unused(dangling)images:

1
$ docker images --no-trunc -aqf"dangling=true" | xargs docker rmi

如果你对不可撤消的数据损失做过极保证金,那么你可以删除(Dangling)Volume(V1.9 and up):

1
$ docker volume ls -qf"dangling=true" | xargs docker volume rm

他们在一个合适的壳牌,别名:

1
2
3
4
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 v1.9.0 release notes
  • 法国电力公司
  • 法国电力公司


To remove old tagged images that are more than a month old:

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

Note that it's fail to remove images that are used by a container,referenced in a reportory,has dependent child images…这可能是你想要的。埃尔斯刚刚添加了

Example of EDOCX1/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/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


其他答案很好,特别是:

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

但我需要在这两个命令中间有一些东西,所以我需要的是filter选项:

1
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 1.13或更高版本,您可以只使用prune命令。对于您的问题,特别是删除旧图像,您需要第一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Remove unused images
docker image prune

# Remove stopped containers.
docker container prune

# Remove unused volumes
docker volume prune

# Remove unused networks
docker network prune

# Command to run all prunes:
docker system prune

我建议不要习惯使用docker system prune命令。我估计用户会无意中删除他们不想删除的内容。就个人而言,我将主要使用docker image prunedocker container prune命令。


This worked for me:

1
docker rmi $(docker images | grep"^<none>" | awk"{print $3}")

到目前为止(Docker版本1.12),我们使用以下命令删除所有正在运行的容器。另外,如果我们想删除卷,可以在下面的命令中使用其各自的标记-v手动删除。

删除所有退出的容器

1
docker rm $(docker ps -q -f status=exited)

删除所有停止的容器

1
docker rm $(docker ps -a -q)

删除所有正在运行和已停止的容器

1
2
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

移除所有容器,无任何标准

1
docker container rm $(docker container ps -aq)

但是,在1.13及以上版本中,为了完成系统和清理,我们可以直接使用以下命令:

1
docker system prune

所有未使用的容器、图像、网络和卷都将被删除。我们还可以使用以下命令来清理各个组件:

1
2
3
4
docker container prune
docker image prune
docker network prune
docker volume prune

我最近写了一个脚本,以便在我的一个服务器上解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash

# Remove all the dangling images
DANGLING_IMAGES=$(docker images -qf"dangling=true")
if [[ -n $DANGLING_IMAGES ]]; then
    docker rmi"$DANGLING_IMAGES"
fi

# Get all the images currently in use
USED_IMAGES=($( \
    docker ps -a --format '{{.Image}}' | \
    sort -u | \
    uniq | \
    awk -F ':' '$2{print $1":"$2}!$2{print $1":latest"}' \
))

# Get all the images currently available
ALL_IMAGES=($( \
    docker images --format '{{.Repository}}:{{.Tag}}' | \
    sort -u \
))

# Remove the unused images
for i in"${ALL_IMAGES[@]}"; do
    UNUSED=true
    for j in"${USED_IMAGES[@]}"; do
        if [["$i" =="$j" ]]; then
            UNUSED=false
        fi
    done
    if [["$UNUSED" == true ]]; then
        docker rmi"$i"
    fi
done

下面是一个清理Docker图像和回收空间的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash -x
## Removing stopped container
docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm

## If you do not want to remove all container you can have filter for days and weeks old like below
#docker ps -a | grep Exited | grep"days ago" | awk '{print $1}' | xargs docker rm
#docker ps -a | grep Exited | grep"weeks ago" | awk '{print $1}' | xargs docker rm

## Removing Dangling images
## There are the layers images which are being created during building a Docker image. This is a great way to recover the spaces used by old and unused layers.

docker rmi $(docker images -f"dangling=true" -q)

## Removing images of perticular pattern For example
## Here I am removing images which has a SNAPSHOT with it.

docker rmi $(docker images | grep SNAPSHOT | awk '{print $3}')

## Removing weeks old images

docker images | grep"weeks ago" | awk '{print $3}' | xargs docker rmi

## Similarly you can remove days, months old images too.

原稿

https://github.com/vishalvsh1/docker-image-cleanup

通常Docker将与图像构建和层相关的所有临时文件保存在

/VAR/LIB/码头工人

此路径是系统的本地路径,通常位于根分区"/"。

您可以装载一个更大的磁盘空间,并将/var/lib/docker的内容移动到新的装载位置,并创建一个符号链接。

这样,即使Docker映像占用空间,它也不会影响您的系统,因为它将使用其他安装位置。

原始日志:管理本地磁盘上的Docker映像


如果你想在前一个月清除图像,你可以试用下一个例子,在前三个月清除图像:

1
2
three_months_old_images=`docker images | grep -vi"<none>" | tr -s ' ' | cut -d"" -f3,4,5,6 | grep"3 months ago" | cut -d"" -f1`
docker rmi $three_months_old_images


我使用这个命令:

1
2
3
4
5
6
7
8
export BEFORE_DATETIME=$(date --date='10 weeks ago' +"%Y-%m-%dT%H:%M:%S.%NZ")
docker images -q | while read IMAGE_ID; do
    export IMAGE_CTIME=$(docker inspect --format='{{.Created}}' --type=image ${IMAGE_ID})
    if [["${BEFORE_DATETIME}">"${IMAGE_CTIME}" ]]; then
        echo"Removing ${IMAGE_ID}, ${BEFORE_DATETIME} is earlier then ${IMAGE_CTIME}"
        docker rmi -f ${IMAGE_ID};
    fi;
done

这将删除创建时间大于10周前的所有图像。


如何删除带标记的图像

  • 先把标签拿出来

  • Docker RMI图像。

    #这可以在一个Docker RMI调用中完成,例如:#docker rmi

  • (本作品2016年11月,Docker版本1.12.2)

    例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ docker images
    REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
    usrxx/the-application   16112805            011fd5bf45a2        12 hours ago        5.753 GB
    usryy/the-application   vx.xx.xx            5af809583b9c        3 days ago          5.743 GB
    usrzz/the-application   vx.xx.xx            eef00ce9b81f        10 days ago         5.747 GB
    usrAA/the-application   vx.xx.xx            422ba91c71bb        3 weeks ago         5.722 GB
    usrBB/the-application   v1.00.18            a877aec95006        3 months ago        5.589 GB

    $ docker rmi usrxx/the-application:16112805 && docker rmi 011fd5bf45a2
    $ docker rmi usryy/the-application:vx.xx.xx && docker rmi 5af809583b9c
    $ docker rmi usrzz/the-application:vx.xx.xx eef00ce9b81f
    $ docker rmi usrAA/the-application:vx.xx.xx 422ba91c71bb
    $ docker rmi usrBB/the-application:v1.00.18 a877aec95006

    例如,脚本删除任何超过2周的内容。

    1
    2
    3
    4
    5
    6
    IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E" (weeks|months|years)")
    TAGS=$(echo"$IMAGESINFO" | awk '{ print $2":" $3 }' )
    IDS=$(echo"$IMAGESINFO" | awk '{ print $1 }' )
    echo remove old images TAGS=$TAGS IDS=$IDS
    for t in $TAGS; do docker rmi $t; done
    for i in $IDS; do docker rmi $i; done

    @vonc already gave a very nice answer,but for completeness here is a little script I have using----and which also nukes any errand docker processes you should have some:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/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


    要删除未运行容器的标记图像,必须使用一个小脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/bin/bash

    # remove not running containers
    docker rm $(docker ps -f"status=exited" -q)

    declare -A used_images

    # collect images which has running container
    for image in $(docker ps | awk 'NR>1 {print $2;}'); do
        id=$(docker inspect --format="{{.Id}}" $image);
        used_images[$id]=$image;
    done

    # loop over images, delete those without a container
    for id in $(docker images --no-trunc -q); do
        if [ -z ${used_images[$id]} ]; then
            echo"images is NOT in use: $id"
            docker rmi $id
        else
            echo"images is in use:     ${used_images[$id]}"
        fi
    done


    几周前移走旧容器。

    docker rm $(docker ps -a | grep"weeks" | awk '{ print $1; }')

    几周前删除旧图像。小心。这将删除几周前创建但新图像可能使用的基本图像。

    docker rmi $(docker images | grep 'weeks' | awk '{ print $3; }')


    如果您希望自动/定期清理退出的容器,并删除正在运行的容器未使用的映像和卷,则可以下载映像meltwater/docker-cleanup

    只是运行:

    1
    docker run -d -v /var/run/docker.sock:/var/run/docker.sock:rw  -v /var/lib/docker:/var/lib/docker:rw --restart=unless-stopped meltwater/docker-cleanup:latest

    默认情况下,每30分钟运行一次。但是,您可以使用此标志以秒为单位设置延迟时间(延迟时间=1800选项)。

    更多详情:https://github.com/meltwater/docker-cleanup/blob/master/readme.md


    1
    docker rm `docker ps -aq`

    黄金

    1
    docker rm $(docker ps -q -f status=exited)


    docker system prune -a

    (要求您确认命令。如果你知道自己在做什么,就用-f来强制跑步。)


    同时修剪所有图像和卷docker system prune -af --volumes


    有Sparrow插件Docker移除悬挂图像,可用于清理停止的容器和未使用(悬挂)的图像:

    $ sparrow plg run docker-remove-dangling-images

    它适用于Linux和Windows操作系统。


    有时我会遇到这样的问题:Docker将分配并继续使用磁盘空间,即使该空间没有分配给任何特定的映像或现有容器。我无意中生成这个问题的最新方法是使用"docker engine"centos build,而不是在RHEL7.1中使用"docker"。似乎发生的是有时容器清理没有成功完成,然后空间永远不会被重用。当我分配的80GB驱动器被/var/lib/docker文件填满时,我必须想出一种创造性的方法来解决这个问题。

    这是我想出来的。首先解决磁盘满错误:

  • 停止Docker:SystemCtl停止Docker
  • 分配了一个安装为say/mnt/docker的新驱动器。
  • 将/var/lib/docker中的所有文件移动到/mnt/docker。我使用了命令:rsync-aphsx--remove source files/var/lib/docker//mnt/docker/
  • 将新驱动器安装到/var/lib/docker。
  • 在这一点上,我不再有一个磁盘满错误,但我仍然浪费了大量的空间。下一步就是要解决这个问题。

  • 启动Docker:SystemCtl启动Docker

  • 保存所有图像:docker save$(docker images s e d-e'/^/d'-e'/^repository/d'-e's,[],:,'-e's,[].,')>/root/docker.img

  • 卸载Docker。

  • 清除/var/lib/docker中的所有内容:rm-射频/var/lib/docker/[cdintv]*

  • 重新安装Docker

  • 启用Docker:SystemCtl启用Docker

  • 启动Docker:SystemCtl启动Docker

  • 恢复图像:Docker Load

  • 启动任何需要运行的持久容器。

  • 这使我的磁盘使用量从Docker的67 GB下降到Docker的6 GB。

    我不建议日常使用这个。但是,当Docker似乎已经失去了对软件错误或意外重启所用磁盘空间的跟踪时,运行它是很有用的。