千家信息网

如何使用Docker多阶段构建来减小镜像大小

发表于:2024-12-04 作者:千家信息网编辑
千家信息网最后更新 2024年12月04日,这篇文章主要为大家展示了"如何使用Docker多阶段构建来减小镜像大小",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"如何使用Docker多阶段构建来减小镜
千家信息网最后更新 2024年12月04日如何使用Docker多阶段构建来减小镜像大小

这篇文章主要为大家展示了"如何使用Docker多阶段构建来减小镜像大小",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"如何使用Docker多阶段构建来减小镜像大小"这篇文章吧。

如何通过 Docker 的多阶段构建功能来大幅度减小镜像大小,适用于需要在 Dockerfile 中构建程式(如 javac),且需要另外安装编译工具链的镜像。(如 Java)

先来学习单词(本文全部采用中文词汇,如需查询外文文档可对照该词汇表。理论上个人不赞成翻译术语):

  • multi-stage 多阶段

  • build 构建

  • image 镜像

  • stage 阶段

再来看一下效果: 原 110M+,现 92M。

对比一下 Dockerfile

优化前 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8ADD . /appWORKDIR /appRUN apk add maven \  && mvn clean package \  && apk del maven \  && mv target/final.jar / \  && cd / \  && rm -rf /app \  && rm -rf /root/.m2ENTRYPOINT java -jar /final.jar

优化后 Dockerfile:

FROM openjdk:8u171-jdk-alpine3.8 as builderADD . /appWORKDIR /appRUN apk add maven \  && mvn clean package \  && apk del maven \  && mv target/final.jar /FROM openjdk:8u181-jre-alpine3.8 as environmentWORKDIR /COPY --from=builder /final.jar .ENTRYPOINT java -jar /final.jar

很明显,优化后的 Dockerfile 新增了 FROM AS 这个命令,并出现了两个 FROM。这就是多阶段构建。

了解一下多阶段构建

多阶段构建是 Docker 17.05 的新增功能,它可以在一个 Dockerfile 中使用多个 FROM 语句,以创建多个 Stages(阶段)。每个阶段间独立(来源请求),可以通过 COPY --from 来获取其它阶段的文件。我们来打个比方,把最终镜像比作一盘菜(炒青椒)。把原料青椒炒完后上桌。

# 对比清单镜像 -> 一盘菜第一个阶段 -> 炒第二个阶段 -> 上桌

两个阶段的目标是做好(生成)最终的菜(镜像)。我们要做的是将第一个阶段「炒」出来的食物进行「上桌」。我们的目标是 做出菜,且 菜盘子(盛菜和中间产物)最轻。

可视化流程如下:

# 做菜流程... 省略原料原料 -> [第一个阶段--炒] # 此时盘子里有炒的工具、炒的结果和中间产物# 这时候开启第二个阶段,只保留炒的结果,而不再需要其它。-> 炒的结果 -> [开始上桌,只保留结果] # 把炒出来的青椒拿来(COPY --from),其它不要-> 最终是一盘菜。

现在应该大致理解多阶段构建的流程了吧。我们把话筒交给 Java,看看在 Dockerfile 中使用编译工具构建一个 JAR,并只保留构建完的 JAR 和运行时交给 Image,其它则扔掉应该怎么做:

# 第一阶段--编译(炒)FROM openjdk:8u171-jdk-alpine3.8 as builder # 自带编译工具ADD . /appWORKDIR /appRUN ... 省略编译和清理工作...# 现在,JAR 已经出炉。JDK 不再需要,所以不能留在镜像中。# 所以我们开启第二阶段--运行(上桌),并扔掉第一阶段的所有文件(包括编译工具)FROM openjdk:8u181-jre-alpine3.8 as environment # 只带运行时# 目前,编译工具等上一阶段的东西已经被我们抛下。目前的镜像中只有运行时,我们需要把上一阶段(炒)的结果拿来,其它不要。COPY --from=0 /final.jar .# 好了,现在镜像只有必要的运行时和 JAR 了。ENTRYPOINT java -jar /final.jar

如上就是多阶段构建的介绍。

使用多阶段构建

多阶段构建的核心命令是 FROM。FORM 对于身经百战的你来说已经不用多讲了。在多阶段构建中,每次 FROM 都会开启一个新的 Stage(阶段),可以看作一个新的 Image(不够准确、来源请求),与其它阶段隔离(甚至包括环境变量)。只有最后的 FROM 才会被纳入 Image 中。

我们来做一个最 simple 的多阶段构建例子:

# Stage 1FROM alpine:3.8WORKDIR /demoRUN echo "Hello, stage 1" > /demo/hi-1.txt# Stage 2FROM alpine:3.8WORKDIR /demoRUN echo "Hello, stage 2" > /demo/hi-2.txt

可以自己构建一下这个 Dockerfile,然后 docker save > docker.tar 看看其中的内容。不出意外应该只有 /demo/hi-2.txt 和 Alpine。

在这个 Dockerfile 中,我们创建了两个阶段。第一个阶段创建 hi-1.txt,第二个阶段创建 hi-2.txt,且第二个阶段会被加入最终 Image,其它不会。

复制文件--阶段间的桥梁

如果阶段间完全隔离,那么多阶段就没有意义--上一个阶段的结果会被完全抛弃,并进入全新的下一阶段。

我们可以通过 COPY 命令来获取其它阶段的文件。在多阶段中使用 COPY 和普通应用完全一致,仅需要添加 -form ` 即可。那么,我们修正上一个例子,使最终镜像包含两个阶段的产物:

# Stage 1FROM alpine:3.8WORKDIR /demoRUN echo "Hello, stage 1" > /demo/hi-1.txt# Stage 2FROM alpine:3.8WORKDIR /demoCOPY --from=0 /demo/hi-1.txt /demoRUN echo "Hello, stage 2" > /demo/hi-2.txt

重新构建并保存(Save),你会发现多了一层 Layer,其中包含 hi-1.txt。

阶段命名--快速识别

对于只有七秒记忆的我们来说,每次使用 stage index 并不是一件很妙的事情。这时候,可以通过阶段命名的方式给它们赋予名字,以方便识别。

为阶段添加名字很简单,只需要在 FROM 后加上 as 即可。

现在,我们更新 Dockerfile,给予阶段名称并使用名称来 COPY。

# Stage 1, it's name is "build1"FROM alpine:3.8 as build1WORKDIR /demoRUN echo "Hello, stage 1" > /demo/hi-1.txt# Stage 2, it's name is "build2"FROM alpine:3.8 as build2WORKDIR /demo# No longer use indexesCOPY --from=build1 /demo/hi-1.txt /demoRUN echo "Hello, stage 2" > /demo/hi-2.txt

重新构建并保存,结果应该同上次相同。

仅构建部分阶段--轻松调试

Docker 还为我们提供了一个很方便的调试方式--仅构建部分阶段。它可以使构建停在某个阶段,并不构建后面的阶段。这可以方便我们调试;区分生产、开发和测试。

仍然沿用上次的 Dockerfile,但使用 --target 参数进行构建:

$ docker build --target build1 .

再次 Save,你会发现只有 build1 的内容。

以上是"如何使用Docker多阶段构建来减小镜像大小"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

阶段 镜像 结果 编译 只有 工具 内容 运行 大小 两个 文件 产物 原料 可以通过 命令 流程 盘菜 篇文章 青椒 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳市商派网络技术有限公司 前程无忧 三国杀几个区用的是一个服务器吗 金融网络安全宣传问答 南通软件开发技术项目实训中心 国家网络安全最新要求 域名服务器英语是什么 把自己游戏数据库 在服务器怎么加一个端口 长沙服务器托管厂家 江西共青团网络安全教育 数据库系统的扩展名是什么 广州云讯互联网科技 网络安全管理制度(意见) dbms是什么数据库系统 全景影像软件开发工程师 黄浦区项目数据库行业 940网络安全考研 中科院内部网络安全责任书 全国手机归属地数据库 河北新能源软件开发制造价格 方向互联网科技 服务器主机能装两个电脑吗 财经网站和经济研究数据库网站 大学生党员网络安全教育 单位内部网络安全巡查 tp5切换数据库分页 网络安全技术笔记本 山西餐饮软件开发品质售后无忧 服务器进入主板阵列卡在哪里 福建大数据卫星授时服务器
0