使用Maven插件構建Spring Boot應用程序的Docker鏡像。
環境准備
1.Linux系統
2.安裝JDK,Maven
3.安裝Docker
應用實踐
1.在應用程序根目錄下添加Dockerfile文件
並在Dockerfile中編輯構建內容:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
2.在項目pom.xml中添加docker鏡像構建插件dockerfile-maven-plugin
<build>
<plugins>
<!-- 使用Maven插件直接將應用打包為一個Docker鏡像 -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
顯然,在插件dockerfile-maven-plugin中配置了2個參數:
<repository>
:指定鏡像倉庫信息及鏡像名稱,如:springio/test-springboot<buildArgs>
:設置構建參數,該參數可以直接在Dockerfile中使用(但是必須在Dockerfile使用ARG指令聲明)
3.執行構建
在Spring Boot應用根目錄下執行構建:
mvn install dockerfile:build
將會看到如下構建日志:
...
[INFO] Building Docker context /home/chench/workspace/java/test-springboot
[INFO]
[INFO] Image will be built as springio/test-springboot:latest
[INFO]
[INFO] Step 1/5 : FROM openjdk:8-jdk-alpine
[INFO]
[INFO] Pulling from library/openjdk
[INFO] Image ff3a5c916c92: Pulling fs layer
[INFO] Image 5de5f69f42d7: Pulling fs layer
[INFO] Image fd869c8b9b59: Pulling fs layer
[INFO] Image 5de5f69f42d7: Downloading
[INFO] Image 5de5f69f42d7: Verifying Checksum
[INFO] Image 5de5f69f42d7: Download complete
[INFO] Image ff3a5c916c92: Downloading
[INFO] Image fd869c8b9b59: Downloading
[INFO] Image ff3a5c916c92: Verifying Checksum
[INFO] Image ff3a5c916c92: Download complete
[INFO] Image ff3a5c916c92: Extracting
[INFO] Image ff3a5c916c92: Pull complete
[INFO] Image 5de5f69f42d7: Extracting
[INFO] Image 5de5f69f42d7: Pull complete
[INFO] Image fd869c8b9b59: Verifying Checksum
[INFO] Image fd869c8b9b59: Download complete
[INFO] Image fd869c8b9b59: Extracting
[INFO] Image fd869c8b9b59: Pull complete
[INFO] Digest: sha256:e82316151c501a2a0f73b3089da8dc867816470a464fcb191db9f88c2343ad53
[INFO] Status: Downloaded newer image for openjdk:8-jdk-alpine
[INFO] ---> 224765a6bdbe
[INFO] Step 2/5 : VOLUME /tmp
[INFO]
[INFO] ---> Running in 99fc0b2bbcf7
[INFO] Removing intermediate container 99fc0b2bbcf7
[INFO] ---> 74c89740c46e
[INFO] Step 3/5 : ARG JAR_FILE
[INFO]
[INFO] ---> Running in 54d9bf00c9c6
[INFO] Removing intermediate container 54d9bf00c9c6
[INFO] ---> 81d324efe92b
[INFO] Step 4/5 : COPY ${JAR_FILE} app.jar
[INFO]
[INFO] ---> f11354b41c33
[INFO] Step 5/5 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
[INFO]
[INFO] ---> Running in 74d40fc4f99c
[INFO] Removing intermediate container 74d40fc4f99c
[INFO] ---> fbc5e8d75beb
[INFO] Successfully built fbc5e8d75beb
[INFO] Successfully tagged springio/test-springboot:latest
[INFO]
[INFO] Detected build of image with id fbc5e8d75beb
[INFO] Building jar: /home/chench/workspace/java/test-springboot/target/test-springboot-0.0.1-dev-docker-info.jar
[INFO] Successfully built springio/test-springboot:latest
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:41 min
[INFO] Finished at: 2018-05-07T10:41:05+08:00
[INFO] Final Memory: 47M/132M
[INFO] ------------------------------------------------------------------------
從構建日志中可以很清晰地看到,一開始下載Maven的依賴配置,隨后就開始使用Dockerfile中的構建指令定制鏡像,並且將項目根路徑作為構建上下文。
另外,在項目的target目錄下將會生成一個名為docker的目錄:
在該docker目錄下存在如下幾個文件:image-id,image-name,repository,tag,其中保存的就是最新構建出來的鏡像信息。
構建完畢之后查看在本地鏡像倉庫是否存在對應鏡像:
$docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
springio/test-springboot latest fbc5e8d75beb 49 seconds ago 138MB
4.驗證鏡像是否正確
$docker run --name test-springboot -d -p 8080:8080 springio/test-springboot
438246b5f8e8ed7808b3127ed8fce867cd162f050135369c02f09cb2cdc8d49d
$docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
438246b5f8e8 springio/test-springboot "java -Djava.securit…" 5 seconds ago Up 4 seconds 0.0.0.0:8080->8080/tcp test-springboot
而且,還可以直接在docker run
命令中傳遞環境變量設置Spring Boot應用程序的運行環境,如:-e "SPRING_PROFILES_ACTIVE=test"
。
$docker run --name test-springboot-env2 -e "SPRING_PROFILES_ACTIVE=test" -p 8080:8080 -d springio/test-springboot
5.將鏡像推送到倉庫
有2種方式可以實現將構建好的Spring Boot應用程序鏡像推送到鏡像倉庫:
(1)構建完畢之后手動推送
mvn dockerfile:push
(2)配置Maven插件在構建完畢之后自動推送
<!-- 使用Maven插件直接將應用打包為一個Docker鏡像 -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
<!-- 鏡像構建完畢之后自動推送到倉庫 -->
<executions>
<execution>
<id>default</id>
<phase>install</phase>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
</plugin>
注意事項
1.可以使用Maven插件便捷地構建Spring Boot應用程序的Docker鏡像,但是最核心的還是如何編寫Dockerfile構建腳本。
2.在使用Maven插件構建Spring Boot應用程序鏡像時,會使用應用程序根路徑作為構建上下文。