Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

์ปจํ…Œ์ด๋„ˆ๋Š” ๋ชจ๋“  ์†Œํ”„ํŠธ์›จ์–ด ๋ฐ ์šด์˜ ์ฒด์ œ ์ข…์†์„ฑ๊ณผ ํ•จ๊ป˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํŒจํ‚ค์ง•ํ•œ ๋‹ค์Œ ์ด๋ฅผ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์— ์ œ๊ณตํ•˜๋Š” ๋ฐ ์„ ํ˜ธ๋˜๋Š” ์ˆ˜๋‹จ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ์—์„œ๋Š” Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

  • Docker ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ Docker ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ ,
  • Cloud-Native Buildpack์„ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค์—์„œ OCI ์ด๋ฏธ์ง€ ์ƒ์„ฑ
  • ๋‹ค์ค‘ ๊ณ„์ธต ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JAR์˜ ์ผ๋ถ€๋ฅผ ์—ฌ๋Ÿฌ ๊ณ„์ธต์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ์ด๋ฏธ์ง€ ์ตœ์ ํ™”.

 ์ฝ”๋“œ ์˜ˆ

์ด ๊ธฐ์‚ฌ์—๋Š” ์ž‘์—… ์ฝ”๋“œ ์˜ˆ์ œ๊ฐ€ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. GitHub์—์„œ .

์ปจํ…Œ์ด๋„ˆ ์šฉ์–ด

๊ธฐ์‚ฌ์— ์‚ฌ์šฉ๋œ ์ปจํ…Œ์ด๋„ˆ ์šฉ์–ด๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€: ํŠน์ • ํ˜•์‹์˜ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ ๋„๊ตฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ: ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€์˜ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ ์—”์ง„: ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฐ๋ชฌ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ ํ˜ธ์ŠคํŠธ: ์ปจํ…Œ์ด๋„ˆ ์—”์ง„์ด ์‹คํ–‰๋˜๋Š” ํ˜ธ์ŠคํŠธ ์ปดํ“จํ„ฐ์ž…๋‹ˆ๋‹ค.
  • ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ: ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๊ฒŒ์‹œํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜ ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • OCI ํ‘œ์ค€์˜คํ”ˆ ์ปจํ…Œ์ด๋„ˆ ์ด๋‹ˆ์…”ํ‹ฐ๋ธŒ(OCI) Linux Foundation ๋‚ด์— ํ˜•์„ฑ๋œ ๊ฒฝ๋Ÿ‰์˜ ๊ฐœ๋ฐฉํ˜• ๊ฑฐ๋ฒ„๋„Œ์Šค ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. OCI ์ด๋ฏธ์ง€ ์‚ฌ์–‘์€ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ์—”์ง„์ด ๋ชจ๋“  ๋นŒ๋“œ ๋„๊ตฌ์—์„œ ์ƒ์„ฑ๋œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋ฐ ๋Ÿฐํƒ€์ž„ ํ˜•์‹์— ๋Œ€ํ•œ ์—…๊ณ„ ํ‘œ์ค€์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋กœ ๋ž˜ํ•‘ํ•˜๊ณ  ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ๊ณต์œ  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„์€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์ด ์ด๋ฏธ์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์••์ถ•์„ ํ‘ผ ๋‹ค์Œ ๊ทธ ์•ˆ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Spring Boot ๋ฒ„์ „ 2.3์€ OCI ์ด๋ฏธ์ง€ ์ƒ์„ฑ์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋„์ปค ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ ๊ตฌํ˜„์ด๋ฉฐ ์˜ˆ์ œ์—์„œ๋Š” Docker๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ด ๋ฌธ์„œ์˜ ๋ชจ๋“  ํ›„์† ์ปจํ…Œ์ด๋„ˆ ์ฐธ์กฐ๋Š” Docker๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๊ตฌ์ถ•

Docker ํŒŒ์ผ์— ๋ช‡ ๊ฐ€์ง€ ์ง€์นจ์„ ์ถ”๊ฐ€ํ•˜๋ฉด Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์šฉ Docker ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ JAR ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  Docker ํŒŒ์ผ ์ง€์นจ์˜ ์ผ๋ถ€๋กœ ํ•„์š”ํ•œ ์„ค์ •์„ ์ ์šฉํ•œ ํ›„ ๊ธฐ๋ณธ JRE ์ด๋ฏธ์ง€ ์œ„์— ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ JAR ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ด„ ์ด๋‹ˆ์…œ ๋ผ์ด์ € ์ข…์†์„ฑ์ด ์žˆ์Œ weblombokะธ actuator. ๋˜ํ•œ API๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜๋จธ์ง€ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. GET๋ฐฉ๋ฒ•.

Dockerfile ๋งŒ๋“ค๊ธฐ

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ปจํ…Œ์ด๋„ˆํ™”ํ•ฉ๋‹ˆ๋‹ค. Dockerfile:

FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/application.jar"]

Docker ํŒŒ์ผ์—๋Š” ๋‹ค์Œ์˜ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. adoptopenjdk, ๊ทธ ์œ„์— JAR ํŒŒ์ผ์„ ๋ณต์‚ฌํ•œ ๋‹ค์Œ ํฌํŠธ๋ฅผ ์—ฝ๋‹ˆ๋‹ค. 8080์š”์ฒญ์„ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ•

๋จผ์ € Maven ๋˜๋Š” Gradle์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” Maven์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

mvn clean package

๊ทธ๋Ÿฌ๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ JAR ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. Docker ์—”์ง„์—์„œ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์ด ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ JAR์„ Docker ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ์ด ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ JAR ํŒŒ์ผ์„ Docker ์ด๋ฏธ์ง€์— ๋„ฃ์Šต๋‹ˆ๋‹ค. docker build์ด์ „์— ์ƒ์„ฑ๋œ Dockerfile์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

docker build  -t usersignup:v1 .

๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชฉ๋ก์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

docker images 

์œ„ ๋ช…๋ น์˜ ์ถœ๋ ฅ์—๋Š” ์ด๋ฏธ์ง€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. usersignup๊ธฐ๋ณธ ์ด๋ฏธ์ง€์™€ ํ•จ๊ป˜ adoptopenjdkDocker ํŒŒ์ผ์— ์ง€์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

REPOSITORY          TAG                 SIZE
usersignup          v1                  249MB
adoptopenjdk        11-jre-hotspot      229MB

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋‚ด๋ถ€์˜ ๋ ˆ์ด์–ด ๋ณด๊ธฐ

์ด๋ฏธ์ง€ ๋‚ด๋ถ€์˜ ๋ ˆ์ด์–ด ์Šคํƒ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค ะธะฝัั‚ั€ัƒะผะตะฝั‚  ์ž ์ˆ˜, ์ด ๋ ˆ์ด์–ด๋ฅผ ๋ณด๋ ค๋ฉด:

dive usersignup:v1

๋‹ค์Œ์€ Dive ๋ช…๋ น์˜ ์ถœ๋ ฅ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. 

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

๋ณด์‹œ๋‹ค์‹œํ”ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ์ด์–ด๋Š” ์ด๋ฏธ์ง€ ํฌ๊ธฐ์˜ ์ƒ๋‹น ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ตœ์ ํ™”์˜ ์ผํ™˜์œผ๋กœ ๋‹ค์Œ ์„น์…˜์—์„œ ์ด ๋ ˆ์ด์–ด์˜ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Buildpack์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ

์กฐ๋ฆฝ ํŒจํ‚ค์ง€ (๋นŒ๋“œํŒฉ)์€ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ PAAS(Platform as a Service) ์ œํ’ˆ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ์šฉ์–ด์ž…๋‹ˆ๋‹ค. 2011๋…„ Heroku์— ์˜ํ•ด ์ถœ์‹œ๋˜์—ˆ์œผ๋ฉฐ ์ดํ›„ Cloud Foundry, Google App Engine, Gitlab, Knative ๋ฐ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์ฑ„ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

ํด๋ผ์šฐ๋“œ ๋นŒ๋“œ ํŒจํ‚ค์ง€์˜ ์žฅ์ 

Buildpack์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ๋•Œ์˜ ์ฃผ์š” ์ด์  ์ค‘ ํ•˜๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ค‘์•™์—์„œ(๋นŒ๋”) ๊ด€๋ฆฌํ•˜๊ณ  ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „ํŒŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋นŒ๋“œ ํŒจํ‚ค์ง€๋Š” ํ”Œ๋žซํผ๊ณผ ๊ธด๋ฐ€ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋นŒ๋“œํŒฉ์€ Docker ์—”์ง„์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•˜๋Š” OCI ์ด๋ฏธ์ง€ ํ˜•์‹์„ ์ง€์›ํ•˜์—ฌ ํ”Œ๋žซํผ ์ „๋ฐ˜์—์„œ ํ‘œ์ค€ํ™”๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

Spring Boot ํ”Œ๋Ÿฌ๊ทธ์ธ ์‚ฌ์šฉ

Spring Boot ํ”Œ๋Ÿฌ๊ทธ์ธ์€ Buildpack์„ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค์—์„œ OCI ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. bootBuildImage์ž‘์—…(Gradle) ๋˜๋Š” spring-boot:build-image๋Œ€์ƒ(Maven) ๋ฐ ๋กœ์ปฌ Docker ์„ค์น˜.

Docker ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ‘ธ์‹œํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ด๋ฏธ์ง€ ์ด๋ฆ„์„ ๋‹ค์Œ์—์„œ ์ง€์ •ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. image tag:

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <image>
      <name>docker.io/pratikdas/${project.artifactId}:v1</name>
    </image>
  </configuration>
</plugin>

Maven์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋ณด์ž build-image์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ ๋ฐ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ์˜ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” Dockerfile์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

mvn spring-boot:build-image

๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:build-image (default-cli) @ usersignup ---
[INFO] Building image 'docker.io/pratikdas/usersignup:v1'
[INFO] 
[INFO]  > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' 0%
.
.
.. [creator]     Adding label 'org.springframework.boot.version'
.. [creator]     *** Images (c311fe74ec73):
.. [creator]           docker.io/pratikdas/usersignup:v1
[INFO] 
[INFO] Successfully built image 'docker.io/pratikdas/usersignup:v1'

์ถœ๋ ฅ์—์„œ ์šฐ๋ฆฌ๋Š” paketo Cloud-Native buildpack์ž‘๋™ํ•˜๋Š” OCI ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ Docker ์ด๋ฏธ์ง€๋กœ ๋‚˜์—ด๋œ ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

docker images 

๊ฒฐ๋ก  :

REPOSITORY                             SIZE
paketobuildpacks/run                  84.3MB
gcr.io/paketo-buildpacks/builder      652MB
pratikdas/usersignup                  257MB

Jib์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ

Jib์€ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์ฒด ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” Google์˜ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค.

๊ตฌ์„ฑ jib-maven-pluginpom.xml์—์„œ:

      <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>2.5.2</version>
      </plugin>

๋‹ค์Œ์œผ๋กœ Maven ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ Jib ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‹คํ–‰ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๊ณ  ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ „๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ๊ธฐ์„œ๋Š” Docker ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

mvn compile jib:build -Dimage=<docker registry name>/usersignup:v1

์œ„์˜ Maven ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

[INFO] Containerizing application to pratikdas/usersignup:v1...
.
.
[INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, io.pratik.users.UsersignupApplication]
[INFO] 
[INFO] Built and pushed image as pratikdas/usersignup:v1
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete

์ถœ๋ ฅ์—๋Š” ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋˜์–ด ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋ฐฐ์น˜๋˜์—ˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ตœ์ ํ™”๋œ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋™๊ธฐ์™€ ๊ธฐ์ˆ 

์ตœ์ ํ™”์—๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ะŸั€ะพะธะทะฒะพะดะธั‚ะตะปัŒะฝะพัั‚ัŒ: ์ปจํ…Œ์ด๋„ˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๊ฐ€ ์ด๋ฏธ์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์—”์ง„์„ ์‹คํ–‰ํ•˜๋Š” ํ˜ธ์ŠคํŠธ๋กœ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์„ ๊ณ„ํš์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ํฐ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์ปจํ…Œ์ด๋„ˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์‹œ์Šคํ…œ์—์„œ ์˜ˆ์•ฝ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง€๊ณ  CI ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง‘๋‹ˆ๋‹ค.
  • ะ‘ะตะทะพะฟะฐัะฝะพัั‚ัŒ: ์ด๋ฏธ์ง€๊ฐ€ ํด์ˆ˜๋ก ์ทจ์•ฝ์ ์ด ์žˆ๋Š” ์˜์—ญ๋„ ๋” ์ปค์ง‘๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€๋Š” ๋ ˆ์ด์–ด ์Šคํƒ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ ๊ฐ ๋ ˆ์ด์–ด๋Š” Dockerfile์˜ ๋ช…๋ น์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ฐ ๋ ˆ์ด์–ด๋Š” ๊ธฐ๋ณธ ๋ ˆ์ด์–ด์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋ธํƒ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Docker ์ด๋ฏธ์ง€๋ฅผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด ๋ ˆ์ด์–ด๋กœ ๊ฐ€์ ธ์™€ ํ˜ธ์ŠคํŠธ์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ ์šฉ๋„ "fat JAR" ๊ธฐ๋ณธ ํŒจํ‚ค์ง• ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‘๊บผ์šด JAR์„ ๋ณด๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ „์ฒด JAR์—์„œ ์•„์ฃผ ์ž‘์€ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ž์ฃผ ๋ฐ”๋€Œ๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€๋Š” Spring Framework ์ข…์†์„ฑ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ตœ์ ํ™” ๊ณต์‹์€ Spring Framework ์ข…์†์„ฑ๊ณผ ๋ณ„๋„์˜ ์ˆ˜์ค€์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฒฉ๋ฆฌํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘ก๋‹ˆ๋‹ค.

๋‘๊บผ์šด JAR ํŒŒ์ผ์˜ ๋Œ€๋ถ€๋ถ„์„ ๊ตฌ์„ฑํ•˜๋Š” ์ข…์†์„ฑ ๊ณ„์ธต์€ ํ•œ ๋ฒˆ๋งŒ ๋‹ค์šด๋กœ๋“œ๋˜์–ด ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์—…๋ฐ์ดํŠธ ๋ฐ ์ปจํ…Œ์ด๋„ˆ ์˜ˆ์•ฝ ์ค‘์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์–‡์€ ๊ณ„์ธต๋งŒ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์— ํ‘œ์‹œ๋œ ๋Œ€๋กœ:

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Buildpack์„ ์‚ฌ์šฉํ•˜์—ฌ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ

Spring Boot 2.3์€ ๋‘๊บผ์šด JAR ํŒŒ์ผ์˜ ์ผ๋ถ€๋ฅผ ๋ณ„๋„์˜ ๋ ˆ์ด์–ด๋กœ ์ถ”์ถœํ•˜์—ฌ ๋ ˆ์ด์–ด๋ง์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์ธตํ™” ๊ธฐ๋Šฅ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉฐ Spring Boot Maven ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <layers>
      <enabled>true</enabled>
    </layers>
  </configuration> 
</plugin>

์ด ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋จผ์ € Buildpack์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•œ ํ›„ ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” Docker๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐœ์‚ฌํ•˜์ž build-image์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ์„ ์œ„ํ•œ Maven ๋Œ€์ƒ:

mvn spring-boot:build-image

Dive๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€์˜ ๋ ˆ์ด์–ด๋ฅผ ๋ณด๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ์ด์–ด(๋นจ๊ฐ„์ƒ‰ ์œค๊ณฝ์„ )๊ฐ€ fat JAR ํ˜•์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ป์€ ๊ฒƒ๊ณผ ๋น„๊ตํ•˜์—ฌ ํ‚ฌ๋กœ๋ฐ”์ดํŠธ ๋ฒ”์œ„์—์„œ ํ›จ์”ฌ ์ž‘๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

Docker๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ

Maven ๋˜๋Š” Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  Docker ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์ธตํ™”๋œ Docker JAR ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Docker๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ ˆ์ด์–ด๋ฅผ ์ถ”์ถœํ•˜๊ณ  ์ด๋ฅผ ์ตœ์ข… ์ด๋ฏธ์ง€์— ๋ณต์‚ฌํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ ˆ์ด์–ด๋ง์ด ํ™œ์„ฑํ™”๋œ Maven์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œํ•œ ํ›„ ๊ฒฐ๊ณผ JAR์˜ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

META-INF/
.
BOOT-INF/lib/
.
BOOT-INF/lib/spring-boot-jarmode-layertools-2.3.3.RELEASE.jar
BOOT-INF/classpath.idx
BOOT-INF/layers.idx

์ถœ๋ ฅ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ JAR์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. spring-boot-jarmode-layertoolsะธ layersfle.idxํŒŒ์ผ. ์ด ์ถ”๊ฐ€ JAR ํŒŒ์ผ์€ ๋‹ค์Œ ์„น์…˜์— ์„ค๋ช…๋œ ๋Œ€๋กœ ๊ณ„์ธตํ™”๋œ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ณ„ ๋ ˆ์ด์–ด์˜ ์ข…์†์„ฑ ์ถ”์ถœ

๊ณ„์ธตํ™”๋œ JAR์—์„œ ๊ณ„์ธต์„ ๋ณด๊ณ  ์ถ”์ถœํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์Šคํ…œ ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -Djarmode=layertools๋‹ฌ๋ฆฌ๋‹ค spring-boot-jarmode-layertools์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋Œ€์‹  JAR:

java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar

์ด ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น ์˜ต์…˜์ด ํฌํ•จ๋œ ์ถœ๋ ฅ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

Usage:
  java -Djarmode=layertools -jar usersignup-0.0.1-SNAPSHOT.jar

Available commands:
  list     List layers from the jar that can be extracted
  extract  Extracts layers from the jar for image creation
  help     Help about any command

์ถœ๋ ฅ์—๋Š” ๋ช…๋ น์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. listextractะธ helpั help๊ธฐ๋ณธ๊ฐ’์ด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…๋ น์„ ์‹คํ–‰ํ•ด๋ณด์ž list์˜ต์…˜:

java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar list
dependencies
spring-boot-loader
snapshot-dependencies
application

๋ ˆ์ด์–ด๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์ข…์†์„ฑ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๋ ˆ์ด์–ด:

๋ ˆ์ด์–ด ์ด๋ฆ„

๋‚ด์šฉ

dependencies

๋ฒ„์ „์— SNAPSHOT์ด ํฌํ•จ๋˜์ง€ ์•Š์€ ๋ชจ๋“  ์ข…์†์„ฑ

spring-boot-loader

JAR ๋กœ๋” ํด๋ž˜์Šค

snapshot-dependencies

๋ฒ„์ „์— SNAPSHOT์ด ํฌํ•จ๋œ ๋ชจ๋“  ์ข…์†์„ฑ

application

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํด๋ž˜์Šค ๋ฐ ๋ฆฌ์†Œ์Šค

๋ ˆ์ด์–ด๋Š” ๋‹ค์Œ์—์„œ ์ •์˜๋ฉ๋‹ˆ๋‹ค. layers.idxDocker ์ด๋ฏธ์ง€์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ํŒŒ์ผ์„ ์ €์žฅํ•˜์„ธ์š”. ์ด๋Ÿฌํ•œ ๋ ˆ์ด์–ด๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ฒซ ๋ฒˆ์งธ ๊ฒ€์ƒ‰ ํ›„ ํ˜ธ์ŠคํŠธ์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต๋งŒ ํ˜ธ์ŠคํŠธ์— ๋‹ค์šด๋กœ๋“œ๋˜๋ฉฐ, ํฌ๊ธฐ๊ฐ€ ์ค„์–ด๋“ค์–ด ์†๋„๊ฐ€ ๋นจ๋ผ์ง‘๋‹ˆ๋‹ค. .

๋ณ„๋„์˜ ๋ ˆ์ด์–ด๋กœ ์ถ”์ถœ๋œ ์ข…์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ๋นŒ๋“œ

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ๋‹จ๊ณ„์— ๊ฑธ์ณ ์ตœ์ข… ์ด๋ฏธ์ง€๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋‹จ๊ณ„ ์กฐ๋ฆฝ . ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ์ข…์†์„ฑ์„ ์ถ”์ถœํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ์ถ”์ถœ๋œ ์ข…์†์„ฑ์„ ์ตœ์ข… ์ด๋ฏธ์ง€์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋‹จ๊ณ„ ๋นŒ๋“œ๋ฅผ ์œ„ํ•ด Dockerfile์„ ์ˆ˜์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

# the first stage of our build will extract the layers
FROM adoptopenjdk:14-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

# the second stage of our build will copy the extracted layers
FROM adoptopenjdk:14-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

์ด ๊ตฌ์„ฑ์„ ๋ณ„๋„์˜ ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. Dockerfile2.

๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ Docker ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.

docker build -f Dockerfile2 -t usersignup:v1 .

์ด ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

Sending build context to Docker daemon  20.41MB
Step 1/12 : FROM adoptopenjdk:14-jre-hotspot as builder
14-jre-hotspot: Pulling from library/adoptopenjdk
.
.
Successfully built a9ebf6970841
Successfully tagged userssignup:v1

Docker ์ด๋ฏธ์ง€๊ฐ€ ์ด๋ฏธ์ง€ ID๋กœ ์ƒ์„ฑ๋œ ํ›„ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ƒ์„ฑ๋œ Docker ์ด๋ฏธ์ง€ ๋‚ด๋ถ€์˜ ๋ ˆ์ด์–ด๋ฅผ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ์ด์ „๊ณผ ๊ฐ™์ด Dive ๋ช…๋ น์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. Dive ๋ช…๋ น์— ๋Œ€ํ•œ ์ž…๋ ฅ์œผ๋กœ ์ด๋ฏธ์ง€ ID ๋˜๋Š” ํƒœ๊ทธ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

dive userssignup:v1

์ถœ๋ ฅ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํฌํ•จ๋œ ๊ณ„์ธต์€ ์ด์ œ 11KB์— ๋ถˆ๊ณผํ•˜๋ฉฐ ์ข…์†์„ฑ์€ ๋ณ„๋„์˜ ๊ณ„์ธต์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค. 

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ตœ์ ํ™”๋œ Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ

๊ฐœ๋ณ„ ๋ ˆ์ด์–ด์˜ ๋‚ด๋ถ€ ์ข…์†์„ฑ ์ถ”์ถœ

์‚ฌ์šฉ์ž ์ง€์ • ์ข…์†์„ฑ์„ ์„ ์–ธํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ•จ๊ป˜ ํŒจํ‚ค์ง•ํ•˜๋Š” ๋Œ€์‹  ์‚ฌ์šฉ์ž ์ง€์ • ์ข…์†์„ฑ์„ ๋ณ„๋„์˜ ๊ณ„์ธต์œผ๋กœ ์ถ”์ถœํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์˜ ํฌ๊ธฐ๋ฅผ ๋”์šฑ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. yml์œ ์‚ฌํ•œ ํŒŒ์ผ ์ด๋ฆ„ layers.idx:

- "dependencies":
  - "BOOT-INF/lib/"
- "spring-boot-loader":
  - "org/"
- "snapshot-dependencies":
- "custom-dependencies":
  - "io/myorg/"
- "application":
  - "BOOT-INF/classes/"
  - "BOOT-INF/classpath.idx"
  - "BOOT-INF/layers.idx"
  - "META-INF/"

์ด ํŒŒ์ผ์—๋Š” layers.idx๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. io.myorg๊ณต์œ  ์ €์žฅ์†Œ์—์„œ ๊ฒ€์ƒ‰๋œ ์กฐ์ง ์ข…์†์„ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ถœ๋ ฅ

์ด ๋ฌธ์„œ์—์„œ๋Š” ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋นŒ๋“œํŒฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ง์ ‘ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋Š” Docker๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹ , ๋จผ์ € ๋‘๊บผ์šด ์‹คํ–‰ ๊ฐ€๋Šฅ JAR ํŒŒ์ผ์„ ๋งŒ๋“  ๋‹ค์Œ Docker ํŒŒ์ผ์— ์ง€์นจ์„ ์ง€์ •ํ•˜์—ฌ ์ด๋ฅผ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋กœ ํŒจํ‚ค์ง•ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ํ˜ธ์ŠคํŠธ์— ์บ์‹œ๋œ ๋ณ„๋„์˜ ๋ ˆ์ด์–ด๋กœ ์ข…์†์„ฑ์„ ๋Œ์–ด์˜ค๊ณ  ์ปจํ…Œ์ด๋„ˆ์˜ ์‹คํ–‰ ์—”์ง„์—์„œ ์˜ˆ์•ฝ ์‹œ๊ฐ„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์”ฌ ๋ ˆ์ด์–ด๊ฐ€ ๋กœ๋“œ๋˜๋Š” ๋ ˆ์ด์–ด๋ง ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ธฐ์‚ฌ์— ์‚ฌ์šฉ๋œ ๋ชจ๋“  ์†Œ์Šค ์ฝ”๋“œ๋Š” ๋‹ค์Œ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊นƒํ—ˆ๋ธŒ .

๋ช…๋ น ์ฐธ์กฐ

๋‹ค์Œ์€ ์ด ๋ฌธ์„œ์—์„œ ์‚ฌ์šฉํ•œ ๋ช…๋ น์— ๋Œ€ํ•œ ๊ฐ„๋žตํ•œ ์š”์•ฝ์ž…๋‹ˆ๋‹ค.

์ปจํ…์ŠคํŠธ ์ง€์šฐ๊ธฐ:

docker system prune -a

Docker ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ:

docker build -f <Docker file name> -t <tag> .

Dockerfile ์—†์ด ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.

mvn spring-boot:build-image

์ข…์†์„ฑ ๋ ˆ์ด์–ด๋ฅผ ๋ด…๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ JAR ํŒŒ์ผ์„ ๋นŒ๋“œํ•˜๊ธฐ ์ „์— spring-boot-maven-plugin์—์„œ ๊ณ„์ธตํ™” ๊ธฐ๋Šฅ์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

java -Djarmode=layertools -jar application.jar list

์ข…์†์„ฑ ๋ ˆ์ด์–ด ์ถ”์ถœ. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ JAR ํŒŒ์ผ์„ ๋นŒ๋“œํ•˜๊ธฐ ์ „์— spring-boot-maven-plugin์—์„œ ๊ณ„์ธตํ™” ๊ธฐ๋Šฅ์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

 java -Djarmode=layertools -jar application.jar extract

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋ชฉ๋ก ๋ณด๊ธฐ

docker images

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋‚ด๋ถ€ ์™ผ์ชฝ์—์„œ ๋ณด๊ธฐ(๋‹ค์ด๋น™ ๋„๊ตฌ๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ):

dive <image ID or image tag>

์ถœ์ฒ˜ : habr.com