偶然的一次机会,解决项目故障的分析过程中,看到项目中有研发团队写好的Dockerfile,居然出现了两个FORM,吸引了我的眼球。和我自己之前写过的文章 Dockerfile构建简单镜像 有所不同,决定一探究竟。

据查阅资料了解到,这个叫分层构建镜像,用于一些特定的环境。

如:使用go语言编译好的二进制文件要放在docker image中使用,就可以使用分层构建

自己使用的系统中没有go环境,以后也不怎么会用到,或者可能会给客户用,不清楚客户的环境,再或者有特定的go版本,就可以使用。

最重要的是,可以最大程度上优化镜像的大小

分层构建结构

FROM {语言构建镜像} as {NAME}
# {语言构建镜像},如go/nodejs/python/maven等需要编译的工具镜像
# {NAME},可自定义,用于第二层调用
# {语言构建镜像} as {NAME},可以理解为重命名的意思
ENV KEY VALUE
# 设置环境变量(可选)
COPY FILE DIR
# 复制语言代码到镜像中
RUN make build
# 以上编译完成

# 以下就是正常的构建镜像了
FROM {最终要构建的镜像}
RUN
...
COPY --from={NAME} /DIR/FILE /DIR
# --from={NAME},这里的NAME就是第一层镜像中的重命名NAME
# 也就是将这个NAME镜像中的文件复制到,现在构建的镜像中
ENTRYPOINT ["sh", "-c", "xxx"]

第一个FORM使用的{语言构建镜像},如go/nodejs/python/maven等。as后可以接自己定义一个{NAME},后面会用到。然后可以在语言环境中编译好自己需要的包。

第二个FORM使用自己最后构建镜像的环境,在对环境进行优化或者其他的操作之后,可以使用COPY --form=来调用第一层镜像,上面提到FROM xxx as yyy,yyy就需要卸载--form后面,然后指定在第一层中构建好的包目录,复制到第二层镜像的目录中就可以了。

以后我遇到类似需求的Dockerfile,自己写了会来更新本文。

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0