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

时间:2015-09-22 17:23:37

标签: docker

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

此外,我还要删除几个月前提取的图像,这些图片具有正确的TAG

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

26 个答案:

答案 0 :(得分:1223)

2016年9月更新:Docker 1.13:PR 26108commit 86de7c0引入了一些新命令,以帮助可视化Docker守护程序数据在磁盘上占用多少空间并允许轻松清理&# 34;不需要"过量。

docker system prune将删除所有悬空数据(即按顺序:容器停止,没有容器的卷和没有容器的图像)。甚至是未使用的数据,false选项。

您还有:

对于未使用的图像,请使用-a(用于删除悬空未图像的图像)。
警告:' 未使用'表示未被任何容器引用的图像":在使用docker image prune -a之前要小心。

正如A L answer中所示,-a将删除所有未使用的图像,而不仅仅是悬空图片......可以是太多了。

docker system prune --all--filter option相结合可能是限制修剪的好方法(docker SDK API 1.28 minimum, so docker 17.04+

  

目前支持的过滤器是:

  • docker xxx prune - 仅删除在给定时间戳之前创建的容器,图像和网络
  • until (<timestamp>)labellabel=<key>label=<key>=<value>label!=<key>) - 仅删除容器,图片,网络和卷(或如果使用label!=<key>=<value>,则不使用指定的标签。

参见&#34; Prune images&#34;举个例子。

原始答案(2016年9月)

我通常会这样做:

label!=...

我有alias for removing those [dangling images] 13docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

  

drmi过滤器找到未使用的图片

这样,删除了标记图像不再引用的任何中间图像。

我对exited processes (containers)

执行相同的第一次
dangling=true

由于haridsv指出in the comments

  

从技术上讲,在清理图像之前应先清理容器,因为这样可以捕获更多悬空图像并减少错误

Jess Frazelle (jfrazelle)bashrc function

alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'

删除旧图像,而不只是&#34;未引用的悬空&#34;图片,您可以考虑docker-gc

  

一个简单的Docker容器和图像垃圾收集脚本。

     
      
  • 删除超过一小时前退出的容器。
  •   
  • 删除之后不属于任何剩余容器的图像。
  •   

答案 1 :(得分:101)

更新第二个(2017-07-08):

使用更新的system prune(再次)参考VonC。不耐烦的人可以使用-f, --force选项跳过提示:

docker system prune -f

不耐烦的鲁莽可以另外删除&#34;未使用的图像,而不仅仅是悬空图像&#34;使用-a, --all选项:

docker system prune -af

https://docs.docker.com/engine/reference/commandline/system_prune/

更新

请参阅使用最近添加的prune命令的VonC's answer。这是相应的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'

参考文献:

答案 2 :(得分:50)

删除超过一个月的旧标记图片:

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

请注意,它失败删除容器使用的图像,在存储库中引用,具有依赖子图像......这可能是您想要的。否则只需添加-f标志。

/etc/cron.daily/docker-gc脚本示例:

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

答案 3 :(得分:20)

其他答案很棒,特别是:

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

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

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

答案 4 :(得分:19)

假设你有Docker 1.13或更高,你可以使用prune命令。对于专门用于删除旧图像的问题,您需要第一个。

# 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命令。

答案 5 :(得分:12)

这对我有用:

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

答案 6 :(得分:10)

到目前为止(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

答案 7 :(得分:7)

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

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

答案 8 :(得分:5)

以下命令将删除48小时以上的图像。

$docker image prune --all --filter until=48h

答案 9 :(得分:5)

这是一个清理Docker镜像并回收空间的脚本。

#!/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中/搬运工

此路径是系统的本地路径,通常位于根分区&#34; /&#34;

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

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

原帖: Manage Docker images on local disk

答案 10 :(得分:3)

如果您想删除几个月前拉 X 的图片,可以尝试以下示例删除三个月前创建的图片:

Animation anim1 = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.animationtext);
anim1.setRepeatCount(Animation.INFINITE);
tviPrueba.startAnimation(anim1);

答案 11 :(得分:3)

我正在使用此命令:

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周前的所有图像。

答案 12 :(得分:2)

@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

答案 13 :(得分:2)

几周前删除旧容器。

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

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

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

答案 14 :(得分:2)

如何删除已标记的图片

  1. docker rmi the tag

  2. docker rmi图片。

    #可以在一个docker rmi中完成,例如:# docker rmi&lt; repo:tag&gt; &LT;图像标识&GT;

  3. (这适用于2016年11月,Docker版本1.12.2)

    e.g。

    $ 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
    

    e.g。脚本删除超过2周的任何内容。

    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
    

答案 15 :(得分:2)

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

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

答案 16 :(得分:1)

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

跑步:

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分钟运行一次。但是,您可以使用此标志以秒为单位设置延迟时间(DELAY_TIME = 1800选项)。

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

答案 17 :(得分:1)

docker system prune -a

(系统会要求您确认该命令。如果您知道自己在做什么,请使用-f强行运行。)

答案 18 :(得分:1)

docker rm $(docker ps -faq)
docker rmi $(docker ps -faq)

-f力

-全部

-q在模式下

答案 19 :(得分:1)

docker rm `docker ps -aq`

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

答案 20 :(得分:1)

如果您自己(从其他一些较旧的基础映像中)构建这些修剪后的映像,请谨慎使用上述基于docker image prune的可接受的解决方案,因为该命令比较钝,并且还会尝试删除该命令所需的所有依赖项您最新的图片(该命令可能应该重命名为docker image*s* prune)。

我为docker映像构建管道(其中有每日构建和标签=日期为YYYYMMDD格式)提出的解决方案是:

# carefully narrow down the image to be deleted (to avoid removing useful static stuff like base images)
my_deleted_image=mirekphd/ml-cpu-py37-vsc-cust

# define the monitored image (tested for obsolescence), which will be usually the same as deleted one, unless deleting some very infrequently built image which requires a separate "clock"
monitored_image=mirekphd/ml-cache

# calculate the oldest acceptable tag (date)
date_week_ago=$(date -d "last week" '+%Y%m%d')

# get the IDs of obsolete tags of our deleted image
# note we use monitored_image to test for obsolescence
my_deleted_image_obsolete_tag_ids=$(docker images --filter="before=$monitored_image:$date_week_ago" | grep $my_deleted_image | awk '{print $3}')

# remove the obsolete tags of the deleted image
# (note it typically has to be forced using -f switch)
docker rmi -f $my_deleted_image_obsolete_tag_ids

答案 21 :(得分:0)

偶尔我遇到Docker将分配并继续使用磁盘空间的问题,即使空间未分配给任何特定图像或现有容器。我不小心生成这个问题的最新方法是在RHEL 7.1中使用“docker-engine”centos build而不是“docker”。似乎发生的事情有时是容器清理没有成功完成,然后空间永远不会被重复使用。当我分配为/ var / lib / docker文件的80GB驱动器时,我不得不想出一个创造性的方法来解决这个问题。

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

  1. 停止泊坞:systemctl stop docker
  2. 分配了一个名为/ mnt / docker的新驱动器。
  3. 将/ var / lib / docker中的所有文件移动到/ mnt / docker。我使用了命令:rsync -aPHSx --remove-source-files / var / lib / docker / / mnt / docker /
  4. 将新驱动器挂载到/ var / lib / docker。
  5. 此时我不再有磁盘已满错误,但我仍然浪费了大量空间。接下来的步骤是照顾它。

    1. 启动Docker:systemctl start docker

    2. 保存所有图片: docker save $(docker images | sed -e'/ ^ / d'-e'/ ^ REPOSITORY / d'-e's,[] [] ,:,' - e',[]。< / em> ,,')&gt; /root/docker.img

    3. 卸载docker。

    4. 清除/ var / lib / docker中的所有内容: rm -rf / var / lib / docker / [cdintv] *

    5. 重新安装docker

    6. 启用docker:systemctl enable docker

    7. 启动docker:systemctl start docker

    8. 恢复图片: docker load&lt; /root/docker.img

    9. 启动您需要运行的所有持久性容器。

    10. 这使我的磁盘使用率从docker的67 GB减少到docker的6 GB。

      我不建议日常使用。但是,当看起来docker已经丢失了使用过的磁盘空间来处理软件错误或意外重启时运行是很有用的。

答案 22 :(得分:0)

也要修剪所有图像和卷
docker system prune -af --volumes

答案 23 :(得分:0)

首先,运行docker images以查看图像列表并将IMAGE HASH ID复制到剪贴板。

运行docker rmi -f <Image>

记住选项-f是强制删除。

答案 24 :(得分:0)

如果有很多的话,删除它们确实很繁琐,但是对我们来说幸运的是Docker有一些命令可以帮助我们消除悬空的图像。在较旧的Docker版本中(今天仍然有效),您可以通过运行docker rmi -f $(docker images -f "dangling=true" -q) 自行删除悬空的镜像。

答案 25 :(得分:0)

我通常使用docker rm -f $(docker ps -a -q)docker system prune来清除所有悬空的容器。