使用GoogleContainerTools下的Jib maven plugin build Spring Boot docker image。
原本建置Spring Boot應用程式的docker image的步驟如下:
- build Spring Boot jar
- 撰寫Dockerfile
- 執行
docker build
例如「Docker build Spring Boot docker image」這篇就是依以上步驟來建置docker image。
除了以上還可使用Google的Jib maven plugin來簡化以上步驟。Jib build的docker image若push到docker registry甚至不需要安裝Docker。
下圖是原本Docker build的過程。
+---------+ +---------+ +-----------------------------------------------+
| Project |---->| JAR |-------+ | Docker Daemon |
+---------+ +---------+ | | +---------------+ build +-----------------+ | +------------------+
+---->| Build context |-------->| Container Image |------>| Container Image |
+------------+ | | +---------------+ | (docker cache) | | | (registry) |
| Dockerfile |----+ | +-----------------+ | +------------------+
+------------+ +-----------------------------------------------+
下圖則是用Jib build的過程。
+---------+ Jib +------------------+
| Project |--------------->| Container Image |
+---------+ | (registry) |
+------------------+
範例環境:
- Java 8
- Spring Boot 2.3.2.RELEASE
- Maven 3.6.3
- Docker 19.03.12
本範例僅在本機用Jib build image到本機的Docker daemon,所以仍要安裝Docker。
參考pom.xml
設定。
application.properties
設定如下。
#context path
server.servlet.context-path=/demo
#port
server.port=8080
新增一個DemoController
處理請求。
package com.abc.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/hello")
public String hello() {
return "Hello World Spring Boot build by Jib Maven plugin";
}
}
開啟命令列工具(終端機 or cmd)將工作目錄移到Spring Boot專案的根目錄下,輸入
mvn compile com.google.cloud.tools:jib-maven-plugin:2.7.0:dockerBuild
用Jib把此Spring Boot專案建置為docker image。如果是第一次用Jib build則過程中會從maven central下載依賴的函式庫。
~/../spring-boot-demo$ mvn compile com.google.cloud.tools:jib-maven-plugin:2.7.0:dockerBuild
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/com/google/cloud/tools/jib-maven-plugin/2.7.0/jib-maven-plugin-2.7.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/cloud/tools/jib-maven-plugin/2.7.0/jib-maven-plugin-2.7.0.pom (4.1 kB at 2.9 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/cloud/tools/jib-maven-plugin/2.7.0/jib-maven-plugin-2.7.0.jar
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/cloud/tools/jib-maven-plugin/2.7.0/jib-maven-plugin-2.7.0.jar (537 kB at 541 kB/s)
[INFO]
[INFO] ----------------------< com.abc:spring-boot-demo >----------------------
[INFO] Building spring-boot-demo 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ spring-boot-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ spring-boot-demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /../spring-boot-demo/target/classes
[INFO]
[INFO] --- jib-maven-plugin:2.7.0:dockerBuild (default-cli) @ spring-boot-demo ---
Downloading from central: ...
...
[INFO] Tagging image with generated image reference spring-boot-demo:0.0.1-SNAPSHOT. If you'd like to specify a different tag, you can set the <to><image> parameter in your pom.xml, or use the -Dimage=<MY IMAGE> commandline flag.
[WARNING] 'mainClass' configured in 'maven-jar-plugin' is not a valid Java class: ${start-class}
[INFO]
[INFO] Containerizing application to Docker daemon as spring-boot-demo:0.0.1-SNAPSHOT...
[WARNING] Base image 'gcr.io/distroless/java:8' does not use a specific image digest - build may not be reproducible
[INFO] Using base image with digest: sha256:90596f62a8ec0701d00845b85dfccf7f53b5e0bb3c49e275d7f19ea6c3e4565d
[INFO]
[INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, com.abc.demo.DemoApplication]
[INFO]
[INFO] Built image to Docker daemon as spring-boot-demo:0.0.1-SNAPSHOT
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:17 min
[INFO] Finished at: 2020-12-12T13:08:43+08:00
[INFO] ------------------------------------------------------------------------
build結束後在命令列輸入docker images
即可看到建置好的專案image。image的REPOSITORY
名稱預設使用Maven專案pom.xml
的<artifactId>
,TAG
則為<version>
。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-demo 0.0.1-SNAPSHOT cc8fbb17a345 50 years ago 148MB
建立時間(CREATED
)在50 years ago(or 48+ years ago)是因為Jib為了達到image的再製性(reproducibility)所以把timestamp移除的結果。
輸入$ docker run -p 8080:8080 --name demo spring-boot-demo:0.0.1-SNAPSHOT
啟動spring-boot-demo
container。
$ docker run -p 8080:8080 --name demo spring-boot-demo:0.0.1-SNAPSHOT
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.2.RELEASE)
2020-12-12 09:44:56.770 INFO 1 --- [ main] c.a.d.DemoApplication : Starting DemoApplication on 4c779dd36d5a with PID 1 (/app/classes started by root in /)
2020-12-12 09:44:56.786 INFO 1 --- [ main] c.a.d.DemoApplication : No active profile set, falling back to default profiles: default
2020-12-12 09:44:58.247 INFO 1 --- [ main] o.s.b.w.e.t.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-12-12 09:44:58.283 INFO 1 --- [ main] o.a.c.c.StandardService : Starting service [Tomcat]
2020-12-12 09:44:58.284 INFO 1 --- [ main] o.a.c.c.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-12-12 09:44:58.396 INFO 1 --- [ main] o.a.c.c.C.[.[.[/demo] : Initializing Spring embedded WebApplicationContext
2020-12-12 09:44:58.397 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1533 ms
2020-12-12 09:44:58.693 INFO 1 --- [ main] o.s.s.c.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-12 09:44:59.002 INFO 1 --- [ main] o.s.b.w.e.t.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '/demo'
2020-12-12 09:44:59.019 INFO 1 --- [ main] c.a.d.DemoApplication : Started DemoApplication in 3.006 seconds (JVM running for 4.172)
在瀏覽器位址輸入http://localhost:8080/demo/hello
會回傳以下。這邊的Spring Boot即為運行的spring-boot-demo
container。
輸入docker ps
檢視運行中的spring-boot-demo
container。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c779dd36d5a spring-boot-demo:0.0.1-SNAPSHOT "java -cp /app/resou…" 9 minutes ago Up 4 seconds 0.0.0.0:8080->8080/tcp demo
參考github。
沒有留言:
張貼留言