Simple Spring Boot on Docker
By: Chiwa Kantawong, Pea
Tags: Spring Boot, Docker

ขอขัดจังหวะ Elasticsearch สัก 1 บทความนะครับ พอดีมีน้องที่ทำงานเก่าถามมาและคิดว่าเป็นประโยชน์​ก็เลยคิดว่าเขียนบทความดีกว่า ซึ่งตัวอย่างเราจะสร้าง Spring Boot Project แบบง่ายๆ แล้วให้สามารถรันบน Docker Container ได้ เราจะไม่กล่าวถึงการติดตั้ง Docker นะครับ มาเริ่มเลยเราจะสร้าง Maven Project กัน

กด Generate ก็จะได้ zip file มาเสร็จแล้ว unzip แล้วเปิดด้วย editor สำหรับตัวอย่างนี้เราจะใช้ Intellij

สร้าง Rest Controller ขึ้นมาหนึ่งตัวนะครับ

package com.zengcode.springbootdocker.controller;



import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;



@RestController

public class HelloController {



@GetMapping(value = "/ping")

public String ping() {

return "pong";

}

}

รองรันดู

ต่อไปเราจะสร้าง Dockerfile

FROM maven:3.6.2-jdk-8 AS build



RUN mkdir -p /usr/src/app/src

RUN chmod 777 -R /usr/src/app/src



COPY src /usr/src/app/src

COPY pom.xml /usr/src/app



RUN mvn -f /usr/src/app/pom.xml clean install -DskipTests



FROM openjdk:8-jre-alpine

RUN apk add --no-cache bash



MAINTAINER Chiwa kantawong



COPY --from=build /usr/src/app/target/spring-boot-docker-*.jar /usr/app/app.jar

RUN sh -c 'touch /usr/app/app.jar'



ADD start.sh /start.sh

RUN chmod 777 /start.sh



EXPOSE 8080



ENTRYPOINT ["/start.sh"]

และสร้าง start.sh ที่เราใช้ start.sh เพื่อบางทีเราต้องการจะส่ง argument หรือคำสั่งพิเศษอะไรอื่นๆ ได้อีกด้วย

#!/bin/sh



java -jar /usr/app/app.jar

ต่อไปเรามา Build Docker Image กันครับ (อย่าลืม stop app ที่เรารันเมื่อกี้นะครับ)

> spring-boot-docker docker build -t zeng/spring-boot-docker .

Sending build context to Docker daemon 8.78MB

Step 1/18 : FROM maven:3.6.2-jdk-8 AS build

— -> 9b5dcb455379

Step 2/18 : RUN mkdir -p /usr/src/app/src

— -> Using cache

— -> bf1b956aa0dd

Step 3/18 : RUN chmod 777 -R /usr/src/app/src

— -> Using cache

— -> 9252ddda1950

Step 4/18 : ADD settings.xml /root/.m2/settings.xml

ADD failed: stat /var/lib/docker/tmp/docker-builder666680021/settings.xml: no such file or directory

➜ spring-boot-docker docker build -t zengcode/spring-boot-docker .

Sending build context to Docker daemon 8.78MB

Step 1/18 : FROM maven:3.6.2-jdk-8 AS build

— -> 9b5dcb455379

Step 2/18 : RUN mkdir -p /usr/src/app/src

— -> Using cache

— -> bf1b956aa0dd

Step 3/18 : RUN chmod 777 -R /usr/src/app/src

— -> Using cache

— -> 9252ddda1950

Step 4/18 : ADD settings.xml /root/.m2/settings.xml

ADD failed: stat /var/lib/docker/tmp/docker-builder364723760/settings.xml: no such file or directory

➜ spring-boot-docker docker build -t zengcode/spring-boot-docker .

Sending build context to Docker daemon 8.78MB

Step 1/15 : FROM maven:3.6.2-jdk-8 AS build

— -> 9b5dcb455379

Step 2/15 : RUN mkdir -p /usr/src/app/src

— -> Using cache

— -> bf1b956aa0dd

Step 3/15 : RUN chmod 777 -R /usr/src/app/src

— -> Using cache

— -> 9252ddda1950

Step 4/15 : COPY src /usr/src/app/src

— -> 5aa1038b9bd3

Step 5/15 : COPY pom.xml /usr/src/app

— -> 49a114a4f1b5

Step 6/15 : RUN mvn -f /usr/src/app/pom.xml clean install -DskipTests

— -> Running in a266009dbdfa

[INFO] Scanning for projects… …… Step 15/15 : ENTRYPOINT [“/start.sh”]

— -> Running in 64e33e84d80b

Removing intermediate container 64e33e84d80b

— -> 0d0565097d06

Successfully built 0d0565097d06

Successfully tagged zengcode/spring-boot-docker:latest

➜ spring-boot-docker

มาดูว่ามันสร้างให้เราจริงๆ ไหม

> spring-boot-docker docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

zengcode/spring-boot-docker latest 0d0565097d06 4 minutes ago 123MB

…..

java latest d23bdf5b1b1b 3 years ago 643MB

➜ spring-boot-docker

เราจะเห็นว่ามี image ชื่อว่า zengcode/spring-boot-docker

ต่อไปเราจะมารัน image นี้ใน Docker Container กัน

> spring-boot-docker docker run — name spring-boot-docker -p 8080:8080 zengcode/spring-boot-docker:latest . ____ _ __ _ _

/\\ / ___’_ __ _ _(_)_ __ __ _ \ \ \ \

( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \ \

\\/ ___)| |_)| | | | | || (_| | ) ) ) )

‘ |____| .__|_| |_|_| |_\__, | / / / /

=========|_|==============|___/=/_/_/_/

:: Spring Boot :: (v2.4.0) 2020–12–01 08:41:32.202 INFO 6 — — [ main] c.z.s.SpringBootDockerApplication : Starting SpringBootDockerApplication v0.0.1-SNAPSHOT using Java 1.8.0_212 on 572054f95b5f with PID 6 (/usr/app/app.jar started by root in /)

2020–12–01 08:41:32.211 INFO 6 — — [ main] c.z.s.SpringBootDockerApplication : No active profile set, falling back to default profiles: default

2020–12–01 08:41:33.773 INFO 6 — — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)

2020–12–01 08:41:33.801 INFO 6 — — [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]

2020–12–01 08:41:33.802 INFO 6 — — [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39]

2020–12–01 08:41:33.897 INFO 6 — — [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext

2020–12–01 08:41:33.897 INFO 6 — — [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1517 ms

2020–12–01 08:41:34.201 INFO 6 — — [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService ‘applicationTaskExecutor’

2020–12–01 08:41:34.436 INFO 6 — — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ‘’

2020–12–01 08:41:34.451 INFO 6 — — [ main] c.z.s.SpringBootDockerApplication : Started SpringBootDockerApplication in 2.996 seconds (JVM running for 3.909)

ลองเข้า

เปิด terminal อีกตัว

>docker ps

แสดงว่า docker ของเรารันได้เรียบร้อย ง่ายไหมล่ะครับ