Docker多步构建更小的Java镜像
譯者按: 最新版Docker將支持多步構(gòu)建(Multi-stage build),這樣使用單個(gè)Dockerfile就可以定義多個(gè)中間鏡像用于構(gòu)建,測(cè)試以及發(fā)布等多個(gè)步驟,并且有效減小最終鏡像的大小。
原文: Creating Smaller Java Image using Docker Multi-stage Build
譯者: Fundebug
為了保證可讀性,本文采用意譯而非直譯。
Github倉(cāng)庫(kù): arun-gupta/docker-java-multistage
DockerCon 2017中與Java開發(fā)者直接相關(guān)的內(nèi)容有:
- Docker多步構(gòu)建(Docker Multi-stage build)
- Oracle JRE in Docker Store
這篇博客介紹了為什么需要****Docker****多步構(gòu)建****(Docker Multi-stage build)****,并且通過(guò)一個(gè)示例展示了如何構(gòu)建更小的Java鏡像。
為什么需要多步構(gòu)建?
為Java應(yīng)用構(gòu)建Docker鏡像意味著編譯源代碼以及打包目標(biāo)代碼。開發(fā)者通常會(huì)使用Maven或者Gradle來(lái)構(gòu)建JAR或WAR文件。若使用Maven鏡像作為基礎(chǔ)鏡像來(lái)構(gòu)建Java應(yīng)用,則需要下載所有Maven依賴。下載的JAR包數(shù)目由pm.xml決定,有可能會(huì)非常多。這樣的話,生成的Docker鏡像中將留下太多多余的文件。
下面為示例Dockerfile:
FROM maven:3.5-jdk-8COPY src /usr/src/myapp/src COPY pom.xml /usr/src/myapp RUN mvn -f /usr/src/myapp/pom.xml clean packageENV WILDFLY_VERSION 10.1.0.Final ENV WILDFLY_HOME /usrRUN 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/wildflyRUN cp /usr/src/myapp/target/people-1.0-SNAPSHOT.war $WILDFLY_HOME/wildfly/standalone/deployments/people.warEXPOSE 8080CMD ["/usr/wildfly/bin/standalone.sh", "-b", "0.0.0.0"]由Dockerfile可知:
- maven:3.5-jdk-8 是基礎(chǔ)鏡像
- 將源代碼拷貝到鏡像中
- Maven用于構(gòu)建應(yīng)用
- 下載并安裝WildFly
- 將生成的.war文件拷貝到WildFly的deployments目錄
- 啟動(dòng)WildFly
這個(gè)Dockefile存在這些問(wèn)題:
- 使用Maven作為基礎(chǔ)鏡像的話,還需要安裝和配置WildFly。
- 構(gòu)建應(yīng)用時(shí)需要下載很多Maven依賴,它們會(huì)繼續(xù)留在鏡像中,但是運(yùn)行應(yīng)用時(shí)并不需要它們。這導(dǎo)致了鏡像過(guò)大。
- 修改WildFly版本則需要修改Dockerfile,并重新構(gòu)建鏡像。如果直接使用WildFly鏡像作為基礎(chǔ)鏡像,情況會(huì)簡(jiǎn)單很多。
- 打包應(yīng)用之前,需要進(jìn)行單元測(cè)試,那么,測(cè)試的依賴也需要留在生成的鏡像中,這其實(shí)是沒(méi)必要的。
當(dāng)然,也可以采用其他方式構(gòu)建Docker鏡像。比如,可以將Dockerfile拆分為兩個(gè)。第一個(gè)Dockerfile以Maven鏡像為基礎(chǔ)鏡像,用于構(gòu)建應(yīng)用,并將構(gòu)建好的.war文件通過(guò)數(shù)據(jù)卷(volume)復(fù)制到共享的目錄;第二個(gè)Dockerfile以WildFly鏡像作為基礎(chǔ)鏡像,從數(shù)據(jù)卷將.war文件拷貝出來(lái)就好了。這個(gè)方法也是有問(wèn)題的,因?yàn)樾枰S護(hù)多個(gè)Dockerfile,并且通過(guò)數(shù)據(jù)卷拷貝文件也不方便。
什么是Docker多步構(gòu)建?
多步構(gòu)建(multi-stage build)允許在Dockerfile中使用多個(gè)FROM指令。兩個(gè)FROM指令之間的所有指令會(huì)生產(chǎn)一個(gè)中間鏡像,最后一個(gè)FROM指令之后的指令將生成最終鏡像。中間鏡像中的文件可以通過(guò)COPY --from=<image-number>指令拷貝,其中image-number為鏡像編號(hào),0為第一個(gè)基礎(chǔ)鏡像。沒(méi)有被拷貝的文件都不會(huì)存在于最終生成的鏡像,這樣可以減小鏡像大小。
FROM指令可以使用as <stage-name>來(lái)指定步驟名稱(stage name):
FROM maven:3.5-jdk-8 as BUILD這樣的話,COPY指令的--from選項(xiàng)可以使用步驟名稱代替鏡像編號(hào)。
下面為示例Dockerfile:
FROM maven:3.5-jdk-8 as BUILDCOPY src /usr/src/myapp/src COPY pom.xml /usr/src/myapp RUN mvn -f /usr/src/myapp/pom.xml clean packageFROM jboss/wildfly:10.1.0.FinalCOPY --from=BUILD /usr/src/myapp/target/people-1.0-SNAPSHOT.war /opt/jboss/wildfly/standalone/deployments/people.war由Dockerfile可知:
- 一共有兩個(gè)FROM指令,因此為兩步構(gòu)建。
- maven:3.5-jdk-8 是第一步構(gòu)建的基礎(chǔ)鏡像。這一步用于構(gòu)建應(yīng)用的WAR文件。這一步的名稱為build。
- jboss/wildfly:10.1.0.Final 是第二步構(gòu)建的基礎(chǔ)鏡像。第一步構(gòu)建的WAR文件通過(guò)COPY --from指令拷貝到WildFly的deloyments目錄。
Docker多步構(gòu)建有什么好處?
- 僅需要一個(gè)Dockerfile來(lái)定義整個(gè)構(gòu)建過(guò)程。這樣,不需要定義多個(gè)Dockerfile,也不需要使用數(shù)據(jù)卷來(lái)拷貝文件。
- 可以為最終鏡像選擇合適的基礎(chǔ)鏡像,來(lái)滿足生產(chǎn)環(huán)境的需求,這樣可以有效減小最終鏡像的大小。另外,構(gòu)建步驟的多余文件都被丟棄了。
- 使用官方的WildFly鏡像作為生產(chǎn)鏡像的基礎(chǔ)鏡像,而不是手動(dòng)安裝和配置WildFly。這樣,WildFly升級(jí)時(shí)將非常方便。
********注:********Docker多步構(gòu)建正在開發(fā)中,還沒(méi)有正式發(fā)布。可以通過(guò) curl -fsSL https://test.docker.com/ | sh命令安裝最新的測(cè)試版Docker試用多步構(gòu)建。
使用第一個(gè)Dockerfile構(gòu)建的鏡像為816MB,而使用多步構(gòu)建的話,鏡像只有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可知,使用多步構(gòu)建可以有效減小鏡像大小。
查看PR #31257,有更加詳細(xì)的討論。
歡迎加入我們Fundebug的****Docker****技術(shù)交流群****: 305097057****。
nodejs-qq-group.jpeg版權(quán)聲明:轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:https://blog.fundebug.com/2017/05/02/about-docker-sock/ 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的Docker多步构建更小的Java镜像的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Excel宏怎么用(用Excel制作热图
- 下一篇: KHALMNPR.exe是什么