【发布时间】:2022-04-29 21:48:17
【问题描述】:
当您使用构建多阶段 Dockerfile 时
docker build -t myimage .
它生成标记为myimage 的最终图像,以及中间图像。为了完全清楚,我们在这里谈论的不是容器,而是图像。它看起来像这样:
看到这些<none> 图像了吗?这些就是我要说的。
以下是一些相关部分:
如果这些中间图像会被自动清除/修剪,则每次构建都会删除构建缓存,因此会强制您每次都重新构建整个图像。
好吧,然后自动修剪是没有意义的。
有些人这样做:
目前,我在我的
docker build -t app .命令之后使用docker image prune -f来清理这些中间图像。
但不幸的是,这不是我能做的。正如一位讨论参与者评论的那样:
它会删除“所有悬空的图像”,因此在共享环境中(如 Jenkins slave),它更像是在自己的脚上开枪。 :)
这是我发现自己所处的场景。
所以在 Docker 方面没有什么需要“修复”的。但是我如何才能删除那些额外的图像,仅从单个特定版本?
更新
在阅读了下面 d4nyll 的非常好的回答之后,这是向前迈出的一大步,我想为这个问题添加更多限制;)首先,让我总结一下答案:
- 可以使用 ARG 将构建 ID 从 CI/CD 传递给
Dockerfilebuilder - 然后可以使用LABEL 语法将构建ID元数据添加到正在构建的舞台图像中
- 然后可以使用docker image prune 命令的
--filter选项仅删除具有当前构建ID 的图像
这是向前迈出了一大步,但我仍在努力研究如何在不增加不必要的复杂性的情况下将其融入我的使用场景。
在我的情况下,要求是编写 Dockerfile 并将其签入源代码控制系统的应用程序开发人员负责确保他们的 Dockerfile 构建的映像令他们满意。他们不需要以特定方式制作所有 Dockerfile,“因此我们的 CI/CD 流程不会中断”。他们只需提供一个Dockerfile 即可生成正确的 docker 镜像。
因此,我真的不能要求他们在Dockerfile 中为每个应用程序添加内容,只是为了 CI/CD 管道。这是 CI/CD 管道应自行处理的所有事情。
我认为实现这项工作的唯一方法是编写一个Dockerfile 解析器,它将检测多阶段构建并在每个阶段注入一个标签,然后构建修改后的Dockerfile。这是一个我非常不愿意添加到 CI/CD 管道中的复杂性。
我有更好(读起来更简单)的选择吗?
【问题讨论】:
-
你有没有试过用这个来清理悬挂的图像:-
docker rmi $(docker images -f "dangling=true" -q) -
@kakabali 是的,它奏效了。但对解决手头的问题没有帮助。
-
抱歉 :-( . 可能有一个单独的区域(另一个内部安装了 docker 的 docker 镜像),您可以在其中推送和镜像到注册表,然后在事后删除这个容器/镜像已经结束了
-
@kakabali docker 在 docker 中不能很好地工作,这是许多人从经验中发现的已知事实,并且 docker 开发人员不建议明确使用它。有很多微妙的问题。如果你有兴趣,谷歌一下。
-
@AndrewSavinykh 有趣的是没有人提到,在重新启动系统后,这些“悬空”图像从 'docker images' 中消失了
标签: docker docker-build