【编者的话】最新版Docker将支持多步构建(Multi-stage build),这样使用单个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

将生成的.war文件拷贝到WildFly的deployments目录

启动WildFly

这个Dockefile存在这些问题:

使用Maven作为基础镜像的话,还需要安装和配置WildFly。

构建应用时需要下载很多Maven依赖,它们会继续留在镜像中,但是运行应用时并不需要它们。这导致了镜像过大。

修改WildFly版本则需要修改Dockerfile,并重新构建镜像。如果直接使用WildFly镜像作为基础镜像,情况会简单很多。

打包应用之前,需要进行单元测试,那么,测试的依赖也需要留在生成的镜像中,这其实是没必要的。

当然,也可以采用其他方式构建Docker镜像。比如,可以将Dockerfile拆分为两个。第一个Dockerfile以Maven镜像为基础镜像,用于构建应用,并将构建好的.war文件通过数据卷(volume)复制到共享的目录;第二个Dockerfile以WildFly镜像作为基础镜像,从数据卷将.war文件拷贝出来就好了。这个方法也是有问题的,因为需要维护多个Dockerfile,并且通过数据卷拷贝文件也不方便。

什么是Docker多步构建?

多步构建(multi-stage build)允许在Dockerfile中使用多个FROM指令。两个FROM指令之间的所有指令会生产一个中间镜像,最后一个FROM指令之后的指令将生成最终镜像。中间镜像中的文件可以通过COPY --from=指令拷贝,其中image-number为镜像编号,0为第一个基础镜像。没有被拷贝的文件都不会存在于最终生成的镜像,这样可以减小镜像大小。

FROM指令可以使用as 来指定步骤名称(stage name):

FROM maven:3.5-jdk-8 as BUILD

这样的话,COPY指令的--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 是第二步构建的基础镜像。第一步构建的WAR文件通过COPY --from指令拷贝到WildFly的deloyments目录。

Docker多步构建有什么好处?

仅需要一个Dockerfile来定义整个构建过程。这样,不需要定义多个Dockerfile,也不需要使用数据卷来拷贝文件。

可以为最终镜像选择合适的基础镜像,来满足生产环境的需求,这样可以有效减小最终镜像的大小。另外,构建步骤的多余文件都被丢弃了。

使用官方的WildFly镜像作为生产镜像的基础镜像,而不是手动安装和配置WildFly。这样,WildFly升级时将非常方便。

注:Docker多步构建正在开发中,还没有正式发布。可以通过 curl -fsSL https://test.docker.com/ | sh命令安装最新的测试版Docker试用多步构建。

使用第一个Dockerfile构建的镜像为816MB,而使用多步构建的话,镜像只有584MB。

docker-java-multistage $ docker images

REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE

people                              multistage          d36a4b82ad87        59 seconds ago      584MB

people                              singlestage         13dbcf8f54f6        5 minutes ago       816MB

可知,使用多步构建可以有效减小镜像大小。

查看PR #31257,有更加详细的讨论。

欢迎加入我们Fundebug的Docker技术交流群: 305097057。

原文: Creating Smaller Java Image using Docker Multi-stage Build

译者: Fundebug

版权声明:

转载时请注明作者Fundebug以及本文地址:

https://blog.fundebug.com/2017 ... sock/

docker java 最小镜像_Docker多步构建更小的Java镜像相关推荐

  1. java镜像升级_Docker多步构建更小的Java镜像

    译者按: 最新版Docker将支持多步构建(Multi-stage build),这样使用单个Dockerfile就可以定义多个中间镜像用于构建,测试以及发布等多个步骤,并且有效减小最终镜像的大小. ...

  2. Docker多步构建更小的Java镜像

    译者按: 最新版Docker将支持多步构建(Multi-stage build),这样使用单个Dockerfile就可以定义多个中间镜像用于构建,测试以及发布等多个步骤,并且有效减小最终镜像的大小. ...

  3. 如何构建尽可能小的容器镜像?

    关注我们获得更多内容 这是Google Developer Advocate Sandeep Dinesh 关于如何充分利用Kubernetes环境的七部分视频和博客系列的第一部分. 主要讲保持容器镜 ...

  4. 驾校分期-众筹项目java前后端分离项目vue(微信小程序+java前后端源码下载)

    可以idea直接打开,mysql数据库项目,前后端分离项目vue,分期可自动设置,自动换算金额 驾校分期-众筹项目java前后端分离项目vue(微信小程序+java前后端源码下载)

  5. java 摧回输入流_收集通信更安闲 谈java串行端口技巧协定.doc

    收集通信更安闲 谈java串行端口技巧协定.doc 还剩 9页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: case SerialPortEvent. ...

  6. multipartfile file java 怎么获取里面的属性_「小程序JAVA实战」小程序的举报功能开发(68)...

    通过点击举报按钮,跳转到举报页面完成举报操作. 后台开发 获取发布人的userId,videoId,创建者的Id controller UserController.java package com. ...

  7. Gradle更小、更快构建APP的奇淫技巧

    请注意,实际结果可能会有所不同,因为它取决于您的项目特征和构建环境,例如项目规模.资源.依赖关系和机器性能. 构建更小App的技巧 APK 的大小将会影响 app 的加载速度.内存占用以及电量消耗.我 ...

  8. jenkins+maven+docker java项目编译、打包、构建镜像、上传私有仓库、web容器部署

    本环境非常简单,主要实现如下流程功能 员工通过eclipse提交java代码---gitlab更新代码----jenkins通过maven编译打包----生成war包----制作docker镜像并上传 ...

  9. 容器云java开发_使用码云构建 Docker 容器镜像并部署到华为云

    华为公有云平台的容器镜像服务开放了对码云代码库的支持. 华为云平台的容器镜像服务(SWR),能够支持从源码到镜像.从镜像到应用的容器镜像全生命周期的管理服务,为用户提供简单易用.安全可靠的镜像管理功能 ...

最新文章

  1. Nature:2020年最佳科学影像,每一张都是壁纸,每一张都是历史
  2. varnish缓存的配置优化(redhat5.4)
  3. CodeForces - 1547G How Many Paths?(强联通缩点+拓扑)
  4. VC中操作INI文件的API
  5. 直接插入排序、冒泡排序实验详解【数据结构实验报告】
  6. Zabbix(五)利用Zabbix部署onealert云告警平台
  7. WebSphere报错指南
  8. Jupyter Notebook的使用02—两种模式的快捷操作
  9. python源码打包成exe、exe反编译、pyd加密防止反编译
  10. 《图解网络硬件》网络硬件通用基础知识
  11. Android 阶段性开发学习知识点(自用)
  12. Windows下强制删除文件或文件夹
  13. 搭建spring-eureka项目时遇到的问题【已解决】
  14. ubuntu10.10下更新无线网卡驱动
  15. AS如何设置ProgressBar宽度以及实现反向进度条
  16. linux下的acr122工具
  17. js调用android代码怎么写,Android端使用WebView注入一段js代码实现js调用android
  18. linux现代时间轮算法,linux2.6定时器的时间轮算法分析
  19. 2010年,我发现了淘宝购物省钱的秘密
  20. 开放系统工程师应用案例之如何协助管理者减轻公司山头的问题

热门文章

  1. 数据库sql创建标量值函数_使用JSON_VALUE()从JSON数据中提取标量值
  2. sql as关键字_SQL AS关键字概述和示例
  3. sklearn学习5-----模型评估(1) 分类度量
  4. react native在static中使用this方法
  5. 字符串对象的charAt函数存在的意义
  6. 开启Windows文件共享必须开启的两个服务
  7. 几何建模研究领域介绍(名词解释)
  8. Web常用字體-Font-Family
  9. mysql C where语句_mysql – 在WHERE子句中使用substr的SELECT语句
  10. python基本运算符