You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何避免`docker image prune -f -a`删除构建中使用的Docker中间镜像?

避免docker image prune删除构建中使用的中间镜像的方案

这个问题确实挺头疼的——定时清理镜像本来是为了节省空间,结果不小心打断正在进行的构建,反而浪费时间和资源。我这里有几个实用的方案,你可以根据自己的环境选择:

1. 按创建时间过滤,只清理“足够老”的镜像

最直接的方式是给docker image prune加上时间过滤条件,只清理创建时间超过N小时/天的未使用镜像。正在构建的中间层肯定是最近生成的,不会被纳入清理范围。

比如,只清理24小时以上的未使用镜像:

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

你可以根据自己的构建频率调整这个时间阈值——如果构建比较频繁,设成12小时;如果构建间隔长,设成48小时都可以。

2. 先检查是否有正在进行的构建,再执行清理

在定时任务的脚本里,先判断当前是否有Docker构建进程在运行,只有当没有构建时才执行清理操作。

方法A:检查docker build进程

pgrep命令查找是否有正在运行的docker build进程:

if ! pgrep -x "docker.build" > /dev/null; then
    docker image prune -f -a
fi

方法B:检查BuildKit构建会话

如果使用docker buildx进行构建,可以查看是否有活跃的构建会话:

if [ -z "$(docker buildx ls | grep -E "(running|active)")" ]; then
    docker image prune -f -a
fi

这个方法更准确,因为BuildKit会用专门的容器来处理构建,通过buildx ls能直接看到是否有正在运行的构建实例。

3. 开启Docker BuildKit,优化缓存管理

Docker BuildKit是新一代的构建引擎,它对构建缓存的管理比传统引擎更智能——正在使用的中间层会被标记为“活跃”,docker image prune默认不会删除这些活跃的缓存层。

开启BuildKit很简单:

  • 临时开启:在执行构建前设置环境变量export DOCKER_BUILDKIT=1
  • 永久开启:编辑/etc/docker/daemon.json,添加以下内容,然后重启Docker服务:
{
  "features": {
    "buildkit": true
  }
}

开启BuildKit后,不仅能避免prune误删构建中的中间层,还能提升构建速度、优化缓存利用率,一举两得。

4. 自定义清理规则,排除构建相关镜像

如果上面的方案都不满足你的需求,还可以自定义脚本,先列出所有可被清理的镜像,再排除掉那些和当前构建相关的镜像。

比如,先获取所有未被容器使用的镜像ID,然后排除掉最近1小时内创建的镜像,再批量删除:

# 获取所有未被使用的镜像ID,排除最近1小时内创建的
IMAGE_IDS=$(docker image ls -q -a --filter "dangling=true" --filter "until=1h")
if [ -n "$IMAGE_IDS" ]; then
    docker rmi $IMAGE_IDS
fi

这个方法更灵活,但需要你根据自己的构建场景调整过滤条件。


内容的提问来源于stack exchange,提问作者variable

火山引擎 最新活动