使用
构建多阶段Dockerfile时docker build -t myimage .
它生成标记为myimage
的最终图像,以及中间图像。要完全清楚,我们在这里谈的不是关于容器,而是关于图像。它看起来像这样:
查看这些<none>
张图片?这就是我所说的。
以下是一些相关部分:
如果这些中间图像会被自动清除/修剪,那么构建缓存将随着每次构建而消失,因此每次强制您重建整个图像。
好吧,修剪然后自动是没有意义的。
有些人这样做:
目前,我在
docker image prune -f
命令之后使用docker build -t app .
来清理那些中间图像。
但不幸的是,这不是我能做的事情。正如一位讨论参与者所评论的那样:
它删除了“所有悬空图像”,因此在共享环境(如Jenkins奴隶)中,它更像是在脚下射击。 :)
这是我发现自己的一个场景。
所以没有什么可以在Docker端“修复”。但是如何才能删除那些额外的图片,仅从一个特定的构建?
更新
从下面的d4nyll中读到非常好的答案,这是向前迈出的一大步,我想在这个问题上添加一些限制;)首先,让我总结一下答案:
Dockerfile
构建器--filter
选项仅删除具有当前构建ID的图像向前迈出了一大步,但我仍然在努力将其融入我的使用场景,而不会增加不必要的复杂性。
在我的情况下,要求是编写Dockerfiles并将其检入源控制系统的应用程序开发人员负责确保他们的Dockerfiles构建满意的映像。他们不需要以特定的方式制作他们所有的Dockerfiles,“所以我们的CI / CD过程不会破坏”。他们只需提供Dockerfile
即可生成正确的泊坞窗图像。
因此,我真的不能请求他们在每个应用程序的Dockerfile
中添加内容,只是为了CI / CD管道。这是CI / CD管道本身可以自行处理的事情。
我能看到做这项工作的唯一方法是编写一个Dockerfile
解析器,它将检测多阶段构建并为每个阶段注入一个标签,然后构建修改后的Dockerfile
。这是一种复杂性,我对添加到CI / CD管道非常犹豫。
我有更好的(阅读更简单)选项吗?
答案 0 :(得分:3)
与ZachEddy
和thaJeztah
mentioned一样,您可以在链接的问题之一中标记中间图像,并根据此标签docker image prune
来标记这些图像。
Dockerfile (使用多阶段构建)
FROM node as builder
LABEL stage=builder
...
FROM node:dubnium-alpine
...
构建图像后,运行:
$ docker image prune --filter label=stage=builder
如果您正在自动化服务器(例如Jenkins)中运行构建,并且只想从该构建中删除中间映像,则可以
Dockerfile
内为此构建ID添加ARG
指令docker build
标志将内部版本ID传递到--build-arg
FROM node as builder
ARG BUILD_ID
LABEL stage=builder
LABEL build=$BUILD_ID
...
FROM node:dubnium-alpine
...
$ docker build --build-arg BUILD_ID .
$ docker image prune --filter label=stage=builder --filter label=build=$BUILD_ID
如果要将构建ID保留在映像中(可能是一种可在容器中访问的文档形式),则可以添加另一个ENV
指令,该指令采用ARG
构建参数的值。这也使您可以使用类似的environment replacement来将标签值设置为内部版本ID。
FROM node as builder
ARG BUILD_ID
ENV BUILD_ID=$BUILD_ID
LABEL stage=builder
LABEL build=$BUILD_ID
...
FROM node:dubnium-alpine
...
答案 1 :(得分:2)
我们正在这样做,在构建时将标签应用于Dockerfile,如下所示:
sed -i '/^FROM/a\
LABEL build_id=${env.BUILD_TAG}\
' Dockerfile
为帮助OP可能为时已晚,但希望这对面临相同问题的人很有用。
答案 2 :(得分:1)
最简单的方法是运行 cmd docker rmi -f $(docker images -f "dangling=true" -q)
答案 3 :(得分:0)
如果根本不想使用缓存,则可以在docker build命令上使用--no-cache = true选项
答案 4 :(得分:0)
您可以运行 docker build 插入另一个参数,这将自动删除中间图像:
docker build --force-rm -t myimage .