์ปจํ ์ด๋๋ ๋ชจ๋ ์ํํธ์จ์ด ๋ฐ ์ด์ ์ฒด์ ์ข ์์ฑ๊ณผ ํจ๊ป ์ ํ๋ฆฌ์ผ์ด์ ์ ํจํค์งํ ๋ค์ ์ด๋ฅผ ๋ค์ํ ํ๊ฒฝ์ ์ ๊ณตํ๋ ๋ฐ ์ ํธ๋๋ ์๋จ์ด ๋์์ต๋๋ค.
์ด ๋ฌธ์์์๋ Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์ด๋ํํ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ๋ค๋ฃน๋๋ค.
- Docker ํ์ผ์ ์ฌ์ฉํ์ฌ Docker ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๊ณ ,
- Cloud-Native Buildpack์ ์ฌ์ฉํ์ฌ ์์ค์์ OCI ์ด๋ฏธ์ง ์์ฑ
- ๋ค์ค ๊ณ์ธต ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ JAR์ ์ผ๋ถ๋ฅผ ์ฌ๋ฌ ๊ณ์ธต์ผ๋ก ๋ถ๋ฆฌํ์ฌ ๋ฐํ์ ์ด๋ฏธ์ง ์ต์ ํ.
์ฝ๋ ์
์ด ๊ธฐ์ฌ์๋ ์์ ์ฝ๋ ์์ ๊ฐ ํจ๊ป ์ ๊ณต๋ฉ๋๋ค. .
์ปจํ ์ด๋ ์ฉ์ด
๊ธฐ์ฌ์ ์ฌ์ฉ๋ ์ปจํ ์ด๋ ์ฉ์ด๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค.
- ์ปจํ ์ด๋ ์ด๋ฏธ์ง: ํน์ ํ์์ ํ์ผ์ ๋๋ค. ๋น๋ ๋๊ตฌ๋ฅผ ์คํํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ก ๋ณํํ๊ฒ ์ต๋๋ค.
- ์ปจํ ์ด๋: ์ปจํ ์ด๋ ์ด๋ฏธ์ง์ ์คํ ๊ฐ๋ฅํ ์ธ์คํด์ค์ ๋๋ค.
- ์ปจํ ์ด๋ ์์ง: ์ปจํ ์ด๋ ์คํ์ ๋ด๋นํ๋ ๋ฐ๋ชฌ ํ๋ก์ธ์ค์ ๋๋ค.
- ์ปจํ ์ด๋ ํธ์คํธ: ์ปจํ ์ด๋ ์์ง์ด ์คํ๋๋ ํธ์คํธ ์ปดํจํฐ์ ๋๋ค.
- ์ปจํ ์ด๋ ๋ ์ง์คํธ๋ฆฌ: ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ๊ฒ์ํ๊ณ ๋ฐฐํฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ผ๋ฐ ์์น์ ๋๋ค.
- OCI ํ์ค: - ์ด๋ ํ๋ ์์ํฌ ๋ด์์ ํ์ฑ๋ ๊ฒฝ๋์ ๊ฐ๋ฐฉํ ๊ด๋ฆฌ ๊ตฌ์กฐ์ ๋๋ค. Linux OCI ์ด๋ฏธ์ง ์ฌ์์ ๋ชจ๋ ์ปจํ ์ด๋ ์์ง์ด ๋ชจ๋ ๋น๋ ๋๊ตฌ๋ก ์์ฑ๋ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ์คํํ ์ ์๋๋ก ์ปจํ ์ด๋ ์ด๋ฏธ์ง ํ์ ๋ฐ ๋ฐํ์์ ๋ํ ์ ๊ณ ํ์ค์ ์ ์ํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์ด๋ํํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ก ๋ํํ๊ณ ํด๋น ์ด๋ฏธ์ง๋ฅผ ๊ณต์ ๋ ์ง์คํธ๋ฆฌ์ ๊ฒ์ํฉ๋๋ค. ์ปจํ ์ด๋ ๋ฐํ์์ ๋ ์ง์คํธ๋ฆฌ์์ ์ด ์ด๋ฏธ์ง๋ฅผ ๊ฒ์ํ๊ณ ์์ถ์ ํผ ๋ค์ ๊ทธ ์์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํฉ๋๋ค.
Spring Boot ๋ฒ์ 2.3์ OCI ์ด๋ฏธ์ง ์์ฑ์ ์ํ ํ๋ฌ๊ทธ์ธ์ ์ ๊ณตํฉ๋๋ค.
๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ปจํ ์ด๋ ๊ตฌํ์ด๋ฉฐ ์์ ์์๋ Docker๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์ด ๋ฌธ์์ ๋ชจ๋ ํ์ ์ปจํ ์ด๋ ์ฐธ์กฐ๋ Docker๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
์ ํต์ ์ธ ๋ฐฉ์์ผ๋ก ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๊ตฌ์ถ
Docker ํ์ผ์ ๋ช ๊ฐ์ง ์ง์นจ์ ์ถ๊ฐํ๋ฉด Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ์ฉ Docker ์ด๋ฏธ์ง๋ฅผ ๋ง๋๋ ๊ฒ์ด ๋งค์ฐ ์ฝ์ต๋๋ค.
๋จผ์ ์คํ ๊ฐ๋ฅํ JAR ํ์ผ์ ์์ฑํ๊ณ Docker ํ์ผ ์ง์นจ์ ์ผ๋ถ๋ก ํ์ํ ์ค์ ์ ์ ์ฉํ ํ ๊ธฐ๋ณธ JRE ์ด๋ฏธ์ง ์์ ์คํ ๊ฐ๋ฅํ JAR ํ์ผ์ ๋ณต์ฌํฉ๋๋ค.
Spring ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. ์ข
์์ฑ์ด ์์ web, lombokะธ 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 ๋ช ๋ น์ ์ถ๋ ฅ ์ผ๋ถ์ ๋๋ค.

๋ณด์๋ค์ํผ ์ ํ๋ฆฌ์ผ์ด์ ๋ ์ด์ด๋ ์ด๋ฏธ์ง ํฌ๊ธฐ์ ์๋น ๋ถ๋ถ์ ์ฐจ์งํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ต์ ํ์ ์ผํ์ผ๋ก ๋ค์ ์น์ ์์ ์ด ๋ ์ด์ด์ ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ ์ถ์ต๋๋ค.
Buildpack์ ์ฌ์ฉํ์ฌ ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๋ง๋ค๊ธฐ
()์ ์์ค ์ฝ๋์์ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๊ธฐ ์ํด ๋ค์ํ PAAS(Platform as a Service) ์ ํ์์ ์ฌ์ฉ๋๋ ์ผ๋ฐ์ ์ธ ์ฉ์ด์ ๋๋ค. 2011๋ Heroku์ ์ํด ์ถ์๋์์ผ๋ฉฐ ์ดํ Cloud Foundry, Google App Engine, Gitlab, Knative ๋ฐ ๊ธฐํ ์ฌ๋ฌ ๊ณณ์์ ์ฑํ๋์์ต๋๋ค.

ํด๋ผ์ฐ๋ ๋น๋ ํจํค์ง์ ์ฅ์
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 257MBJib์ ์ฌ์ฉํ์ฌ ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๋ง๋ค๊ธฐ
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 ์ด๋ฏธ์ง๋ฅผ ๋ ์ง์คํธ๋ฆฌ์์ ๊ฐ์ ธ์ค๋ฉด ๋ ์ด์ด๋ก ๊ฐ์ ธ์ ํธ์คํธ์ ์บ์๋ฉ๋๋ค.
์คํ๋ง ๋ถํธ ์ฉ๋ ๊ธฐ๋ณธ ํจํค์ง ํ์์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. ๋๊บผ์ด JAR์ ๋ณด๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ์ฒด JAR์์ ์์ฃผ ์์ ๋ถ๋ถ์ ์ฐจ์งํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๊ฐ์ฅ ์์ฃผ ๋ฐ๋๋ ๋ถ๋ถ์ ๋๋ค. ๋๋จธ์ง๋ Spring Framework ์ข ์์ฑ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
์ต์ ํ ๊ณต์์ Spring Framework ์ข ์์ฑ๊ณผ ๋ณ๋์ ์์ค์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฉ๋ฆฌํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค.
๋๊บผ์ด JAR ํ์ผ์ ๋๋ถ๋ถ์ ๊ตฌ์ฑํ๋ ์ข ์์ฑ ๊ณ์ธต์ ํ ๋ฒ๋ง ๋ค์ด๋ก๋๋์ด ํธ์คํธ ์์คํ ์ ์บ์๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํธ ๋ฐ ์ปจํ ์ด๋ ์์ฝ ์ค์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ๊ณ์ธต๋ง ๊ฐ์ ธ์ต๋๋ค. ์ด ๋ค์ด์ด๊ทธ๋จ์ ํ์๋ ๋๋ก:

๋ค์ ์น์ ์์๋ 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-imageDive๋ฅผ ์คํํ์ฌ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง์ ๋ ์ด์ด๋ฅผ ๋ณด๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ๋ ์ด์ด(๋นจ๊ฐ์ ์ค๊ณฝ์ )๊ฐ fat JAR ํ์์ ์ฌ์ฉํ์ฌ ์ป์ ๊ฒ๊ณผ ๋น๊ตํ์ฌ ํฌ๋ก๋ฐ์ดํธ ๋ฒ์์์ ํจ์ฌ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.

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์ถ๋ ฅ์๋ ๋ช
๋ น์ด ํ์๋ฉ๋๋ค. list, extractะธ helpั help๊ธฐ๋ณธ๊ฐ์ด ๋ฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ๋ช
๋ น์ ์คํํด๋ณด์ list์ต์
:
java -Djarmode=layertools -jar target/usersignup-0.0.1-SNAPSHOT.jar listdependencies
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:v1Docker ์ด๋ฏธ์ง๊ฐ ์ด๋ฏธ์ง ID๋ก ์์ฑ๋ ํ ํ๊ทธ๊ฐ ์ง์ ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ์์ฑ๋ Docker ์ด๋ฏธ์ง ๋ด๋ถ์ ๋ ์ด์ด๋ฅผ ๊ฒ์ฌํ๊ธฐ ์ํด ์ด์ ๊ณผ ๊ฐ์ด Dive ๋ช ๋ น์ ์คํํฉ๋๋ค. Dive ๋ช ๋ น์ ๋ํ ์ ๋ ฅ์ผ๋ก ์ด๋ฏธ์ง ID ๋๋ ํ๊ทธ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
dive userssignup:v1์ถ๋ ฅ์์ ๋ณผ ์ ์๋ฏ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ด ํฌํจ๋ ๊ณ์ธต์ ์ด์ 11KB์ ๋ถ๊ณผํ๋ฉฐ ์ข ์์ฑ์ ๋ณ๋์ ๊ณ์ธต์ ์บ์๋ฉ๋๋ค.

๊ฐ๋ณ ๋ ์ด์ด์ ๋ด๋ถ ์ข ์์ฑ ์ถ์ถ
์ฌ์ฉ์ ์ง์ ์ข
์์ฑ์ ์ ์ธํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
๊ณผ ํจ๊ป ํจํค์งํ๋ ๋์ ์ฌ์ฉ์ ์ง์ ์ข
์์ฑ์ ๋ณ๋์ ๊ณ์ธต์ผ๋ก ์ถ์ถํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
๊ณ์ธต์ ํฌ๊ธฐ๋ฅผ ๋์ฑ ์ค์ผ ์ ์์ต๋๋ค. 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 -aDocker ํ์ผ์ ์ฌ์ฉํ์ฌ ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๋ง๋ค๊ธฐ:
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
