docker 多阶段构建_使用Docker多阶段构建来创建较小的Java映像

docker 多阶段构建

与Java开发人员直接相关的DockerCon 2017上的两个公告是:

该博客解释了Docker多阶段构建的目的,并提供了示例说明它们如何帮助我们生成更小,更高效的Java Docker映像。

只是给我看代码: github.com/arun-gupta/docker-java-multistage

有什么问题

为Java应用程序构建Docker映像通常涉及构建应用程序并将生成的工件打包到映像中。 Java开发人员可能会使用Maven或Gradle来构建JAR或WAR文件。 如果您使用Maven基本映像来构建应用程序,则它将从配置的存储库中下载所需的依赖项并将它们保留在映像中。 本地存储库中的JAR数量可能会很大,具体取决于pom.xml的依赖项数量。 这可能会在图像中留下很多杂物。

让我们看一个示例Dockerfile:

FROM maven:3.5-jdk-8
 
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package
 
ENV WILDFLY_VERSION 10.1.0.Final
ENV WILDFLY_HOME /usr
 
RUN cd $WILDFLY_HOME && curl http://download.jboss.org/wildfly/$WILDFLY_VERSION/wildfly-$WILDFLY_VERSION.tar.gz | tar zx && mv $WILDFLY_HOME/wildfly-$WILDFLY_VERSION $WILDFLY_HOME/wildfly
 
RUN cp /usr/src/myapp/target/people-1.0-SNAPSHOT.war $WILDFLY_HOME/wildfly/standalone/deployments/people.war
 
EXPOSE 8080
 
CMD ["/usr/wildfly/bin/standalone.sh", "-b", "0.0.0.0"]

在此Dockerfile中:

  • maven:3.5-jdk-8用作基础映像
  • 应用程序源代码已复制到图像
  • Maven用于构建应用程序工件
  • 已下载并安装WildFly
  • 生成的工件被复制到WildFly的deployments目录
  • 终于,WildFly开始了

这种流程有几个问题:

  • maven用作基本映像限制了映像中可用的功能。 这要求WildFly被明确下载和配置。
  • 构建工件会下载所有Maven依赖项。 这些保留在映像中,并且在运行时不需要。 这会在运行时导致图像大小不必要的膨胀。
  • 更改WildFly版本将需要更新Dockerfile。 如果我们可以jboss/wildfly使用jboss/wildfly基本映像,这会容易得多。
  • 另外,单元测试可以在打包工件和图像创建之后的集成测试之前运行。 再次不需要测试依赖项和结果来将其存在于生产映像中。

还有其他构建Docker映像的方法。 例如,将Dockerfile分为两个文件。 然后,第一个文件将构建工件,并使用卷映射将工件复制到公共位置。 然后,第二个文件将拾取生成的工件,然后使用精简基础图像。 这种方法还存在需要分别维护多个Dockerfile的问题。 另外,两个Dockerfile之间存在带外切换。

让我们看看如何通过多阶段构建解决这些问题。

什么是Docker多阶段构建?

多阶段构建允许在Dockerfile中使用多个FROM语句。 每个FROM语句之后直到下一个语句的指令都会创建一个中间映像。 最终的FROM语句是最终的基础映像。 可以使用COPY --from=<image-number>复制中间阶段的工件,对于第一个基本图像,从0开始。 未复制的工件将被丢弃。 这样可以使最终图像保持精简,并且仅包含相关的伪像。

FROM语法已更新为使用as <stage-name>指定阶段名称。 例如:

FROM maven:3.5-jdk-8 as BUILD

这允许使用阶段名称而不是带有--from选项的数字。

让我们看一个示例Dockerfile:

FROM maven:3.5-jdk-8 as BUILD
 
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package
 
FROM jboss/wildfly:10.1.0.Final
 
COPY --from=BUILD /usr/src/myapp/target/people-1.0-SNAPSHOT.war /opt/jboss/wildfly/standalone/deployments/people.war

在此Dockerfile中:

  • 有两个FROM指令。 这意味着这是一个两阶段的构建。
  • maven:3.5-jdk-8是第一个构建的基础映像。 这用于为应用程序构建WAR文件。 第一阶段称为BUILD
  • jboss/wildfly:10.1.0.Final是构建的第二个也是最终的基础映像。 使用COPY --from语法将第一阶段生成的WAR文件复制到此阶段。 该文件直接复制到WildFly部署目录中。

让我们看一下这种方法的一些优点。

Docker多阶段构建的优势

  • 一个Dockerfile定义了整个构建过程。 不需要单独的Dockerfile,然后使用卷映射协调“构建” Dockerfile和“运行” Dockerfile之间的工件转移。
  • 可以适当选择最终映像的基础映像,以满足运行时需求。 这有助于减小运行时映像的整体大小。 此外,在中间阶段将废弃构建时产生的碎片。
  • 使用标准WildFly基本映像,而不是手动下载和配置发行版。 如果发布了更新的标签,这将使更新映像变得更加容易。

使用单个Dockerfile构建的映像大小为816MB。 相比之下,使用多阶段构建构建的映像大小为584MB。

因此,使用多阶段有助于创建更小的图像。

当然,可以使用maven:jdk-8-alpine图像。 但是随后,您必须创建或找到使用jdk-8-alpine或类似工具构建的WildFly映像。 但是问题仍然存在,例如maven存储库,两个Dockerfile,使用卷映射或其他类似技术共享工件。

阅读PR#31257中的更多讨论。

如前所述,完整的代码可在github.com/arun-gupta/docker-java-multistage上找到

注册Docker Online Meetup以获取DockerCon 2017回顾。

翻译自: https://www.javacodegeeks.com/2017/04/creating-smaller-java-image-using-docker-multi-stage-build.html

docker 多阶段构建

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值