如何删除旧的和未使用的 Docker 图片
How to remove old and unused Docker images
当运行 Docker时间长了,系统里的图片很多。如何安全地一次性删除所有未使用的 Docker 图像以释放存储空间?
此外,我还想删除几个月前拉取的图像,这些图像具有正确的TAG
。
所以,我并不是要求只删除未标记的图像。我正在寻找一种方法来删除一般未使用的图像,其中包括未标记的图像和其他图像,例如几个月前使用正确 TAG
.
提取的图像
(原回答见下)
2016 年 9 月更新:Docker 1.13:PR 26108 and commit 86de7c0 引入了一些新命令以帮助可视化 space docker 守护程序数据在磁盘上的占用量并允许轻松清理“不需要的”多余部分。
docker system prune
将删除所有悬空数据(即按顺序:容器停止、没有容器的卷和没有容器的图像)。甚至未使用的数据,带有 -a
选项。
您还有:
对于未使用的图像,使用docker image prune -a
(用于删除悬挂的和未使用的图像)。
警告:'unused' 的意思是“镜像没有被任何容器引用”:使用 -a
.
之前要小心
如 A L's 中所示,docker system prune --all
将删除所有 未使用的 图像,而不仅仅是悬挂的图像......这可能有点太多了。
结合 docker xxx prune
与 --filter
option can be a great way to limit the pruning (docker SDK API 1.28 minimum, so docker 17.04+)
The currently supported filters are:
until (<timestamp>)
- 仅删除在给定时间戳 之前创建的容器、图像和网络
label
(label=<key>
, label=<key>=<value>
, label!=<key>
, or label!=<key>=<value>
) - 仅删除容器、图像、网络和卷(或没有,以防使用label!=...
)指定的标签。
示例请参见“Prune images”。
原始答案(2016 年 9 月)
我经常这样做:
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
我有一个[用于删除那些 dangling images: drmi
]13
的别名
The dangling=true
filter finds unused images
这样,标记图像不再引用的任何中间图像都会被删除。
我先 exited processes (containers)
alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'
作为haridsv points out :
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:
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
}
要删除旧图像,而不仅仅是“未引用的悬挂”图像,您可以考虑 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.
@VonC 已经给出了一个非常好的答案,但为了完整起见,这里有一个我一直在使用的小脚本---如果你有一些,它也会破坏任何差事 Docker 进程:
#!/bin/bash
imgs=$(docker images | awk '/<none>/ { print }')
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
如果你想删除 X 个月前拉取的图像,你可以尝试下面的例子,删除三个月前创建的图像:
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
docker rm `docker ps -aq`
或
docker rm $(docker ps -q -f status=exited)
更新第二个(2017-07-08)
(再次)参考 VonC,使用更近的 system prune
。不耐烦的可以用-f, --force
选项跳过提示:
docker system prune -f
不耐烦和鲁莽可以使用-a, --all
选项额外删除“未使用的图像而不仅仅是悬挂的图像”:
docker system prune -af
https://docs.docker.com/engine/reference/commandline/system_prune/
更新
参考使用最近添加的prune
命令。这里对应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
如果您对不可撤销的数据丢失[=74]采取了极度谨慎 =],然后您可以删除未使用的(悬空的)卷(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'
参考资料
要删除超过一个月的旧标记图像:
$ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
| grep ' months' | awk '{ print }' \
| 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 }' | 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
这对我有用:
docker rmi $(docker images | grep "^<none>" | awk "{print }")
我最近在我的一台服务器上写了一个脚本来解决这个问题:
#!/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 ':' '{print ":"}!{print ":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 图像并回收 space。
#!/bin/bash -x
## Removing stopped container
docker ps -a | grep Exited | awk '{print }' | 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 }' | xargs docker rm
#docker ps -a | grep Exited | grep "weeks ago" | awk '{print }' | 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 }')
## Removing weeks old images
docker images | grep "weeks ago" | awk '{print }' | xargs docker rmi
## Similarly you can remove days, months old images too.
原剧本
https://github.com/vishalvsh1/docker-image-cleanup
通常Docker将所有与图像构建和图层相关的临时文件保存在
/var/lib/docker
此路径是系统本地路径,通常位于根分区,"/"。
您可以安装更大的磁盘 space 并将 /var/lib/docker
的内容移动到新的安装位置并制作一个符号 link.
这样,即使 Docker 个图像占用 space,它也不会影响您的系统,因为它会使用其他安装位置。
要删除没有容器 运行 的标记图像,您将不得不使用一个小脚本:
#!/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 ;}'); 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 将分配并继续使用磁盘 space 的问题,即使 space 未分配给任何特定图像或现有容器。我意外产生这个问题的最新方法是在 RHEL 7.1 中使用“docker-engine”centos build 而不是“docker”。似乎发生的情况是有时容器清理没有成功完成,然后 space 永远不会被重用。当我分配为 /
的 80GB 驱动器充满了 /var/lib/docker
个文件时,我不得不想出一种创造性的方法来解决这个问题。
这是我想出的。先解决磁盘满错误:
停止 docker: systemctl stop docker
分配了一个新的驱动器,如 /mnt/docker
.
将 /var/lib/docker
中的所有文件移动到 /mnt/docker
中。我使用了命令:
rsync -aPHSx --remove-source-files /var/lib/docker/ /mnt/docker/
将新驱动器安装到 /var/lib/docker
。
此时我不再有磁盘已满的错误,但我仍然在浪费大量 space。接下来的步骤就是解决这个问题。
开始 Docker: systemctl start docker
保存所有图片:
docker save $(docker images |sed -e '/^<none>/d' -e '/^REPOSITORY/d' -e 's,[ ][ ]*,:,' -e 's,[ ].*,,') > /root/docker.img
卸载docker.
擦除/var/lib/docker
中的所有内容:
rm -rf /var/lib/docker/[cdintv]*
重新安装docker
启用docker:systemctl enable docker
开始 docker: systemctl start docker
恢复图像:
docker load < /root/docker.img
启动您需要的任何持久容器运行ning。
这使我的磁盘使用量从 docker 的 67 GB 下降到 docker 的 6 GB。
我不推荐日常使用。但它对 运行 很有用,因为它看起来像 docker 丢失了已用磁盘的踪迹 space 对软件错误或意外重新启动。
如何删除标记的图像
docker 首先 rmi 标签
docker rmi 图像。
# 可以在一次 docker rmi 调用中完成,例如:#
docker rmi
(2016 年 11 月有效,Docker 版本 1.12.2)
例如
$ 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 周的任何内容。
IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E " (weeks|months|years)")
TAGS=$(echo "$IMAGESINFO" | awk '{ print ":" }' )
IDS=$(echo "$IMAGESINFO" | awk '{ print }' )
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
删除几周前的旧容器。
docker rm $(docker ps -a | grep "weeks" | awk '{ print ; }')
删除几周前的旧图片。当心。这将删除几周前创建但您的新图像可能正在使用的基础图像。
docker rmi $(docker images | grep 'weeks' | awk '{ print ; }')
假设您有 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 prune
和 docker container prune
命令。
到目前为止(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
我正在使用这个命令:
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 周前的所有图像。
如果您希望 automatically/periodically 清理退出的容器并删除 运行ning 容器未使用的图像和卷,您可以下载图像 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
docker system prune -a
(系统会要求您确认命令。如果您知道自己在做什么,请使用 -f
强制执行 运行。)
其他答案都很棒,具体来说:
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
希望对您有所帮助:)
有 sparrow 插件 docker-remove-dangling-images 可以用来清理停止的容器和未使用的(悬挂的)图像:
$ sparrow plg run docker-remove-dangling-images
它适用于 Linux 和 Windows OS。
同时修剪所有图像和卷
docker system prune -af --volumes
docker rm $(docker ps -faq)
docker rmi $(docker ps -faq)
-f力
-全部
-q 模式
首先,运行 docker images
查看图像列表并将图像哈希 ID 复制到剪贴板。
运行 docker rmi -f <Image>
记住选项-f
是强制删除。
根据doc,以下命令将删除超过 48 小时的图像。
$ docker image prune --all --filter until=48h
如果您自己构建这些修剪过的图像(来自其他一些较旧的基础图像),请小心上面基于 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 }')
# 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
如果你有很多,删除它们真的很乏味,但对我们来说幸运的是 Docker 有一些命令可以帮助我们消除悬挂图像。在 Docker 的旧版本中(今天仍然有效),您可以通过 运行 docker rmi -f $(docker images -f "dangling=true" -q)
.
自行删除悬空图像
我通常会 docker rm -f $(docker ps -a -q)
和 docker system prune
来清除所有悬挂的容器。
当运行 Docker时间长了,系统里的图片很多。如何安全地一次性删除所有未使用的 Docker 图像以释放存储空间?
此外,我还想删除几个月前拉取的图像,这些图像具有正确的TAG
。
所以,我并不是要求只删除未标记的图像。我正在寻找一种方法来删除一般未使用的图像,其中包括未标记的图像和其他图像,例如几个月前使用正确 TAG
.
(原回答见下)
2016 年 9 月更新:Docker 1.13:PR 26108 and commit 86de7c0 引入了一些新命令以帮助可视化 space docker 守护程序数据在磁盘上的占用量并允许轻松清理“不需要的”多余部分。
docker system prune
将删除所有悬空数据(即按顺序:容器停止、没有容器的卷和没有容器的图像)。甚至未使用的数据,带有 -a
选项。
您还有:
对于未使用的图像,使用docker image prune -a
(用于删除悬挂的和未使用的图像)。
警告:'unused' 的意思是“镜像没有被任何容器引用”:使用 -a
.
如 A L's docker system prune --all
将删除所有 未使用的 图像,而不仅仅是悬挂的图像......这可能有点太多了。
结合 docker xxx prune
与 --filter
option can be a great way to limit the pruning (docker SDK API 1.28 minimum, so docker 17.04+)
The currently supported filters are:
until (<timestamp>)
- 仅删除在给定时间戳 之前创建的容器、图像和网络
label
(label=<key>
,label=<key>=<value>
,label!=<key>
, orlabel!=<key>=<value>
) - 仅删除容器、图像、网络和卷(或没有,以防使用label!=...
)指定的标签。
示例请参见“Prune images”。
原始答案(2016 年 9 月)
我经常这样做:
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
我有一个[用于删除那些 dangling images: drmi
]13
The
dangling=true
filter finds unused images
这样,标记图像不再引用的任何中间图像都会被删除。
我先 exited processes (containers)
alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")'
作为haridsv points out
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:
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
}
要删除旧图像,而不仅仅是“未引用的悬挂”图像,您可以考虑 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.
@VonC 已经给出了一个非常好的答案,但为了完整起见,这里有一个我一直在使用的小脚本---如果你有一些,它也会破坏任何差事 Docker 进程:
#!/bin/bash
imgs=$(docker images | awk '/<none>/ { print }')
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
如果你想删除 X 个月前拉取的图像,你可以尝试下面的例子,删除三个月前创建的图像:
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
docker rm `docker ps -aq`
或
docker rm $(docker ps -q -f status=exited)
更新第二个(2017-07-08)
(再次)参考 VonC,使用更近的 system prune
。不耐烦的可以用-f, --force
选项跳过提示:
docker system prune -f
不耐烦和鲁莽可以使用-a, --all
选项额外删除“未使用的图像而不仅仅是悬挂的图像”:
docker system prune -af
https://docs.docker.com/engine/reference/commandline/system_prune/
更新
参考prune
命令。这里对应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
如果您对不可撤销的数据丢失[=74]采取了极度谨慎 =],然后您可以删除未使用的(悬空的)卷(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'
参考资料
要删除超过一个月的旧标记图像:
$ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
| grep ' months' | awk '{ print }' \
| 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 }' | 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
这对我有用:
docker rmi $(docker images | grep "^<none>" | awk "{print }")
我最近在我的一台服务器上写了一个脚本来解决这个问题:
#!/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 ':' '{print ":"}!{print ":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 图像并回收 space。
#!/bin/bash -x
## Removing stopped container
docker ps -a | grep Exited | awk '{print }' | 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 }' | xargs docker rm
#docker ps -a | grep Exited | grep "weeks ago" | awk '{print }' | 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 }')
## Removing weeks old images
docker images | grep "weeks ago" | awk '{print }' | xargs docker rmi
## Similarly you can remove days, months old images too.
原剧本
https://github.com/vishalvsh1/docker-image-cleanup
通常Docker将所有与图像构建和图层相关的临时文件保存在
/var/lib/docker
此路径是系统本地路径,通常位于根分区,"/"。
您可以安装更大的磁盘 space 并将 /var/lib/docker
的内容移动到新的安装位置并制作一个符号 link.
这样,即使 Docker 个图像占用 space,它也不会影响您的系统,因为它会使用其他安装位置。
要删除没有容器 运行 的标记图像,您将不得不使用一个小脚本:
#!/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 ;}'); 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 将分配并继续使用磁盘 space 的问题,即使 space 未分配给任何特定图像或现有容器。我意外产生这个问题的最新方法是在 RHEL 7.1 中使用“docker-engine”centos build 而不是“docker”。似乎发生的情况是有时容器清理没有成功完成,然后 space 永远不会被重用。当我分配为 /
的 80GB 驱动器充满了 /var/lib/docker
个文件时,我不得不想出一种创造性的方法来解决这个问题。
这是我想出的。先解决磁盘满错误:
停止 docker:
systemctl stop docker
分配了一个新的驱动器,如
/mnt/docker
.将
/var/lib/docker
中的所有文件移动到/mnt/docker
中。我使用了命令:rsync -aPHSx --remove-source-files /var/lib/docker/ /mnt/docker/
将新驱动器安装到
/var/lib/docker
。
此时我不再有磁盘已满的错误,但我仍然在浪费大量 space。接下来的步骤就是解决这个问题。
开始 Docker:
systemctl start docker
保存所有图片:
docker save $(docker images |sed -e '/^<none>/d' -e '/^REPOSITORY/d' -e 's,[ ][ ]*,:,' -e 's,[ ].*,,') > /root/docker.img
卸载docker.
擦除
/var/lib/docker
中的所有内容:rm -rf /var/lib/docker/[cdintv]*
重新安装docker
启用docker:
systemctl enable docker
开始 docker:
systemctl start docker
恢复图像:
docker load < /root/docker.img
启动您需要的任何持久容器运行ning。
这使我的磁盘使用量从 docker 的 67 GB 下降到 docker 的 6 GB。
我不推荐日常使用。但它对 运行 很有用,因为它看起来像 docker 丢失了已用磁盘的踪迹 space 对软件错误或意外重新启动。
如何删除标记的图像
docker 首先 rmi 标签
docker rmi 图像。
# 可以在一次 docker rmi 调用中完成,例如:# docker rmi
(2016 年 11 月有效,Docker 版本 1.12.2)
例如
$ 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 周的任何内容。
IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E " (weeks|months|years)")
TAGS=$(echo "$IMAGESINFO" | awk '{ print ":" }' )
IDS=$(echo "$IMAGESINFO" | awk '{ print }' )
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
删除几周前的旧容器。
docker rm $(docker ps -a | grep "weeks" | awk '{ print ; }')
删除几周前的旧图片。当心。这将删除几周前创建但您的新图像可能正在使用的基础图像。
docker rmi $(docker images | grep 'weeks' | awk '{ print ; }')
假设您有 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 prune
和 docker container prune
命令。
到目前为止(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
我正在使用这个命令:
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 周前的所有图像。
如果您希望 automatically/periodically 清理退出的容器并删除 运行ning 容器未使用的图像和卷,您可以下载图像 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
docker system prune -a
(系统会要求您确认命令。如果您知道自己在做什么,请使用 -f
强制执行 运行。)
其他答案都很棒,具体来说:
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
希望对您有所帮助:)
有 sparrow 插件 docker-remove-dangling-images 可以用来清理停止的容器和未使用的(悬挂的)图像:
$ sparrow plg run docker-remove-dangling-images
它适用于 Linux 和 Windows OS。
同时修剪所有图像和卷
docker system prune -af --volumes
docker rm $(docker ps -faq)
docker rmi $(docker ps -faq)
-f力
-全部
-q 模式
首先,运行 docker images
查看图像列表并将图像哈希 ID 复制到剪贴板。
运行 docker rmi -f <Image>
记住选项-f
是强制删除。
根据doc,以下命令将删除超过 48 小时的图像。
$ docker image prune --all --filter until=48h
如果您自己构建这些修剪过的图像(来自其他一些较旧的基础图像),请小心上面基于 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 }')
# 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
如果你有很多,删除它们真的很乏味,但对我们来说幸运的是 Docker 有一些命令可以帮助我们消除悬挂图像。在 Docker 的旧版本中(今天仍然有效),您可以通过 运行 docker rmi -f $(docker images -f "dangling=true" -q)
.
我通常会 docker rm -f $(docker ps -a -q)
和 docker system prune
来清除所有悬挂的容器。