问题描述
感谢Docker的多阶段构建,我们可以在一个环境中编译一些构件,并在另一个环境中执行它们。结果,有两个镜像,其中最后一个对应于最后一个阶段,并且提供的标签被定义为标记;中间(的镜像)没有标签,但它们仍然存在。
问题:是否可以使用多阶段构建从一个Dockerfile创建一系列定义阶段的标记镜像?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在多阶段构建中,可以构建和标记任何阶段。只需使用docker build
命令的--target
选项即可。例如:
docker build --target jdk -t myapp-jdk:v1 .
docker build --target jre -t myapp:v1 .
使用层缓存,较早的步骤将从缓存中重用,而不是每次都从头开始重新运行,因此多次运行构建到不同的目标几乎没有任何副作用。
方案2
使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是使用LABEL
功能在多阶段构建中,然后在构建完成后根据标签进行标记。
优点:
– 只需一次将构建上下文汇总在一起
– 构建完成后,标记的命令速度快
以下是一个示例,讨论了如何使用LABEL
在多阶段构建中进行标记的方法:
FROM node as builder-stage
LABEL builder=true
FROM node as app-stage
LABEL builder=false
现在,可以使用以下命令来过滤、排序并提取最新的构建阶段的镜像ID:
docker images --filter "label=builder=true" --format '{{.CreatedAt}}\t{{.ID}}' | sort -nr | head -n 1 | cut -f2
请注意,在下一个构建阶段中删除标签是很重要的。
这种方法对我来说非常有效。
总结
在Docker的多阶段构建中,可以使用--target
选项构建和标记任何阶段。另一种方法是使用LABEL
功能在多阶段构建中进行标记。这两种方法都可以实现从一个Dockerfile创建一系列定义阶段的标记镜像。
请注意,以上解决方案仅供参考,具体操作可能因版本差异而有所不同。在进行任何更改之前,请确保备份您的数据和配置文件。
参考链接:
– Docker多阶段构建官方文档
– Docker多阶段构建中标记中间构建阶段的讨论