偶然的一次机会,解决项目故障的分析过程中,看到项目中有研发团队写好的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,自己写了会来更新本文。