สร้าง Docker ของ Spring Boot กันเถอะ

Phayao Boonon
3 min readSep 2, 2018

--

เมื่อเราสร้าง Spring Boot Application ได้แล้ว ซึ่งอาจจะสร้าง Microservice หรือ Web Application ในกระบวนการของ DevOps การทำ CI/CD อาจจะต้องสร้าง และ deploy ด้วย Docker ดังนั้นการสร้าง docker image จึ่งเป็นขึ้นตอนที่สำคัญของกระบวนการนี้ ผมจึงลองหาวิธีที่สร้าง docker image 3 วิธี มาแชร์กันครับ

  1. Docker build command
  2. Maven plugin
  3. Official Maven Docker image

สร้าง Spring Boot Application

ก่อนที่เราจะ deploy ด้วย Docker นั้นเราก็จะต้องมี Application ก่อน ซึ่งในบทความนี้ผมจะสร้าง Maven project อย่างง่ายเพื่อที่จะ focus ไปที่การสร้าง Docker image

เมื่อลองรัน application ด้วยคำสั่ง mvn spring-boot:run และลองใช้ Postman เพื่อทดสอบว่า application ของเราทำงานได้หรือไม่ ถ้าทำงานได้ก็จะ response กลับมาเป็น Hello Docker

Docker build command

วิธีนี้จะเป็นการใช้ docker command เพื่อสร้าง docker image ขึ้นมา เริ่มจากสร้าง Dockerfile ใน project และใส่คำสั่งต่างๆ เพื่อเป็นขั้นตอนการสร้าง docker image ของ Spring Boot project ดังนี้

  • FROM — เป็นการใช้ openjdk:8-jdk-alpine image เป็น base image ซึ่งเป็น OpenJDK 8 runtime ขนาดเล็กบน Alpine Linux
  • VOLUME — Volume เป็นการกำหนดสำหรับข้อมูลที่สร้างขึ้นโดย container บน Host OS VOLUME ["/data"] เป็น /tmp
  • EXPORT — เป็นการกำหนด Port ของ ​container ที่จะให้ภายนอกสามารถเข้าถึง application ได้ โดยกำหนดให้เป็น port 8080
  • AGE — เป็นการกำหนดตัวแปรด้วย default value ซึ่งสามารถแทนที่ตัวแปรนี้ได้จากส่งตัวแปรเข้ามาขณะ build กำหนดเป็นตำแหน่งของไฟล์ JAR เป็น JAR_FILE=target/hello-docker-0.0.1-SNAPSHOT.jar
  • ADD — เป็นคำสั่งที่ใช้ copy ไฟล์ใหม่และ directory เข้าไปใน docker image ซึ่งก็เป็นการกำหนดให้เพิ่มไฟล์ JAR เป็น app.jar
  • ENTRYPOINT — เป็นการระบุว่าจะรัน application ในแบบ executable อย่างไรใน container ซึ่งก็เป็นการใช้คำสั่งของ java เรียกไฟล์ app.jar

สร้างไฟล์ JAR ของ application ด้วยคำสั่ง maven จะได้ไฟล์ JAR ใน target/*.JAR

$ mvn package

สร้าง docker image ด้วยคำสั่ง docker build เป็นว่าเราสามารถสร้าง docker image ได้สำเร็จ (-t เป็นการกำหนด tag ให้กับ image)

$ docker build -t hello-docker .Sending build context to Docker daemon  16.44MB
Step 1/6 : FROM openjdk:8-jdk-alpine
---> 5801f7d008e5
Step 2/6 : VOLUME /tmp
---> Using cache
---> 91cbd40de2cb
Step 3/6 : EXPOSE 8080
---> Using cache
---> a21c0ec80d09
Step 4/6 : ARG JAR_FILE=target/hello-docker-0.0.1-SNAPSHOT.jar
---> Using cache
---> 267014c24e40
Step 5/6 : ADD ${JAR_FILE} hello-docker.jar
---> Using cache
---> b52825450f15
Step 6/6 : ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/hello-docker.jar"]
---> Using cache
---> 1a03f0f2db5a
Successfully built 1a03f0f2db5a

สามารถตรวจสอบ docker image ที่สร้างด้วยคำสั่ง docker image ls

$ docker image lsREPOSITORY      TAG         IMAGE ID        CREATED           SIZE
hello-docker latest 1a03f0f2db5a 8 seconds ago 119MB

ลองรัน docker image ด้วยคำสั่ง docker run

$ docker run -p 9000:8080 hello-docker.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.4.RELEASE)......--- [main] : Started Application in 5.24 seconds (JVM running for ..

ทดลองรัน application ใน container ของ docker image ด้วยคำสั่ง docker run

$ docker run -d -p 9000:8080 hello-docker

-p 9000:8080 เป็นการเชื่อมโยง port 8080 ของ container เป็น port 9000 ดังนั้นสามารถใช้ Postman เพื่อ request ไปที่ localhost:9000/ จะ response กลับมาเป็น Hello Docker

ตรวจสอบ container ที่รันอยู่ด้วยคำสั่ง docker container ls จะแสดงรายการของ container ทั้งหมดที่รันอยู่ในเครื่อง

$ docker container lsCONTAINER ID IMAGE         COMMAND                CREATED
cf08936afdc6 hello-docker "java -Djava.securit…" About a minute ago

สามารถหยุด container ได้ด้วยคำสั่ง docker container stop ตามด้วย container id ที่ต้องการหยุด

$ docker container stop cf08936afdc6

Maven plugin

วิธีนี้จะเป็นการใช้ maven plugin ในการสร้าง docker image ซึ่งเป็นวิธีที่ง่ายกว่าการใช้ docker command โดยเพิ่ม plugin นี้เข้าไปในไฟล์ pom.xml ดังนี้

หลังจากที่เพิ่ม plugin เข้าไปในไฟล์ pom.xml เรียบร้อยแล้วก็ลอง build docker image ด้วยคำสั่ง maven

$ mvn package dockerfile:build

ที่ใช้คำสั่ง package ก่อนคำสั่ง dockerfile:build เพราะว่าเราต้องสร้างไฟล์ JAR ก่อนที่จะสร้าง docker image และเราสามารถตรวจสอบ image ด้วยคำสั่ง docker

$ docker image lsREPOSITORY            TAG            IMAGE ID       CREATED  
iphayao/hello-docker 0.0.1-SNAPSHOT ecfb89f8741f 3 minutes ago

ทดลองรัน docker ด้วยคำสั่ง docker run แต่ว่าจะต้องระบุ TAG ด้วยเนื่องจากใน pom.xml เรากำหนดให้ TAG เป็น project.version

$ docker run -d -p 9000:8080 iphayao/hello-docker:0.0.1-SNAPSHOT

Official Maven Docker image

วิธีนี้น่าจะเป็นวิธีที่ง่ายที่สุดเพราะว่าเราไม่ต้องสร้าง docker image เลยเพียงแต่ใช้คำสั่ง docker run ใช้ Maven image ดังนี้

$ docker run -it --rm --name hello-docker -v "$PWD":/usr/src/app -v "$HOME"/.m2:/root/.m2 -w /usr/src/app -d -p 9000:8080 maven:3.3-jdk-8 mvn clean spring-boot:run

-it —อนุญาติให้เชื่อมต่อ container ด้วย pseudo-TTY

-v — ผูก mount volume

-w — working directory ภายใน container

--rm — ลบ container อัตโนมัติเมื่อ exit

--name — กำหนดชื่อให้กับ container

ตรวจสอบ docker container ที่รันเมื่อสักครู่ จะเห็นว่ามี container รันอยู่

$ docker container lsCONTAINER ID  IMAGE            COMMAND                 CREATED
ea77925e6f48 maven:3.3-jdk-8 "/usr/local/bin/mvn-…" 7 seconds ago

สรุป

จากวิธีการต่างๆ ในการสร้าง Docker image ที่ได้กล่าวไปแล้วนั้นเป็นเพียงวิธีการหนึ่งเท่านั้น ซึ่งอาจจะมีอีกหลายวิธี วิธีที่ใช้ docker command อาจจะเป็นวิธีที่ยุ่งยากที่สุด แต่ถ้ามองในมุมของการเรียนรู้ docker แล้วเป็นวิธีที่เหมาะสม และวิธีที่ใช้ maven plugin เป็นวิธีที่ง่ายโดยใช้คำสั่งที่สั้นและเข้าใจง่าย และวิธีสุดท้ายใช้ maven image เป็นวิธีที่ขั้นตอนสั้นที่สุดแต่คำสั่งจะยาวที่สุดเช่นกัน แต่จะไม่ได้สร้าง docker image แต่จะรัน image โดยตรง

--

--

Phayao Boonon
Phayao Boonon

Written by Phayao Boonon

Software Engineer 👨🏻‍💻 Stay Hungry Stay Foolish

No responses yet