網頁

2020/11/29

Docker build Spring Boot docker image

使用Docker建構Spring Boot的docker image。

本篇參考Spring Boot官方教學的「Spring Boot with Docker」。

範例環境:

  • macOS Catalina
  • Docker 19.03.12
  • Java 8
  • Maven
  • Spring Boot 2.3.2.RELEASE
  • IntelliJ IDEA Commnuity

首先建立Spring Boot專案

參考pom.xml設定。


application.properties設定如下。

application.properties

#context path
server.servlet.context-path=/demo
#port
server.port=8080


新增一個DemoController類別處理請求。

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 running in Docker container";
    }
}


在本機啟動專案並在瀏覽器輸入http://localhost:8080/demo/hello會回傳以下。



執行Maven package將Spring Boot打包成jar檔,執行後會在專案下多了target目錄,裡面有打包生成的spring-boot-demo-0.0.1-SNAPSHOT.jar,這個jar待會在docekr build時會被複製成container檔案目錄中的demo.jar






在Spring Boot專案根目錄新增檔案命名為Dockerfile(不用副檔名)內容如下。Dockerfile為Docker build image的指令檔。

Dockerfile

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} demo.jar
ENTRYPOINT ["java","-jar","/demo.jar"]

下面為Dockerfile每一行指令的簡單說明。

  • FROM openjdk:8-jdk-alpine:Spring Boot image使用的base image。
  • ARG JAR_FILE=target/*.jar:定義一個變數名稱為JAR_FILE,值為target/*.jar
  • COPY ${JAR_FILE} demo.jar:將build context的JAR_FILE變數的檔案複製到container檔案目錄的demo.jar
  • ENTRYPOINT ["java","-jar","/demo.jar"]:在container執行java -jar /demo.jar

接著開啟終端機(terminal)將目錄移到Spring Boot專案根目錄,也就是Dockerfile的所在目錄。在命令列輸入docker build -t spring-boot-demo .開始建構Spring Boot的docker image。

  • docker build為Docker建構image的指令。
  • -t後接image的名稱,這邊命名為spring-boot-demo
  • .意思為以當前目錄為build context。
~/../workspace/spring-boot-demo$ docker build -t spring-boot-demo .
Sending build context to Docker daemon  20.68MB
Step 1/4 : FROM openjdk:8-jdk-alpine
8-jdk-alpine: Pulling from library/openjdk
e7c96db7181b: Pull complete
f910a506b6cb: Pull complete
c2274a1a0e27: Pull complete
Digest: sha256:94792824df2df33402f201713f932b58cb9de94a0cd524164a0f2283343547b3
Status: Downloaded newer image for openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/4 : ARG JAR_FILE=target/*.jar
 ---> Running in 759ce2247143
Removing intermediate container 759ce2247143
 ---> 672602f922c9
Step 3/4 : COPY ${JAR_FILE} demo.jar
 ---> 6f47dc5639d3
Step 4/4 : ENTRYPOINT ["java","-jar","/demo.jar"]
 ---> Running in 88bc2c8c8dcd
Removing intermediate container 88bc2c8c8dcd
 ---> b5f1c7728ed9
Successfully built b5f1c7728ed9
Successfully tagged spring-boot-demo:latest

輸入docker images檢視建構好的spring-boot-demo image。

$ docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
spring-boot-demo                   latest              b5f1c7728ed9        55 minutes ago      124MB

輸入$ docker run -p 8080:8080 --name demo spring-boot-demo啟動spring-boot-demo container。

  • -p 8080:8080將本機的8080對映到container的8080 port;
  • --name demo將container名稱設定為demo

命令執行後在終端機出現以下Spring Boot的啟動訊息。

$ docker run -p 8080:8080 --name demo spring-boot-demo

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.2.RELEASE)

2020-11-29 13:09:26.275  INFO 1 --- [           main] c.a.d.DemoApplication                    : Starting DemoApplication v0.0.1-SNAPSHOT on 94b804c3ea20 with PID 1 (/demo.jar started by root in /)
2020-11-29 13:09:26.304  INFO 1 --- [           main] c.a.d.DemoApplication                    : No active profile set, falling back to default profiles: default
2020-11-29 13:09:28.511  INFO 1 --- [           main] o.s.b.w.e.t.TomcatWebServer              : Tomcat initialized with port(s): 8080 (http)
2020-11-29 13:09:28.572  INFO 1 --- [           main] o.a.c.c.StandardService                  : Starting service [Tomcat]
2020-11-29 13:09:28.572  INFO 1 --- [           main] o.a.c.c.StandardEngine                   : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-11-29 13:09:28.743  INFO 1 --- [           main] o.a.c.c.C.[.[.[/demo]                    : Initializing Spring embedded WebApplicationContext
2020-11-29 13:09:28.743  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2315 ms
2020-11-29 13:09:29.220  INFO 1 --- [           main] o.s.s.c.ThreadPoolTaskExecutor           : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-29 13:09:29.618  INFO 1 --- [           main] o.s.b.w.e.t.TomcatWebServer              : Tomcat started on port(s): 8080 (http) with context path '/demo'
2020-11-29 13:09:29.654  INFO 1 --- [           main] c.a.d.DemoApplication                    : Started DemoApplication in 4.543 seconds (JVM running for 6.89)

在瀏覽器位址輸入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
94b804c3ea20        spring-boot-demo    "java -jar /demo.jar"   12 minutes ago      Up 12 minutes       0.0.0.0:8080->8080/tcp   demo

參考github


除了以上自行撰寫Dockerfile並用Docker build image外,也可以利用更方便的Jib maven plugin來建置docker image


沒有留言:

張貼留言