๊ฐ๋ฐ์ผ์ง
[๋์ปค] ๋์ปค ์ต์ ํ - ๋์ปค ๋ ์ด์ด ์บ์ฑ์ ํ์ฉํด์ ์๊ฐ ์ค์ด๊ธฐ! (Layered jar, bootjar, ๋ฉํฐ์คํ ์ด์ง ๋น๋) ๋ณธ๋ฌธ
[๋์ปค] ๋์ปค ์ต์ ํ - ๋์ปค ๋ ์ด์ด ์บ์ฑ์ ํ์ฉํด์ ์๊ฐ ์ค์ด๊ธฐ! (Layered jar, bootjar, ๋ฉํฐ์คํ ์ด์ง ๋น๋)
doublejune 2025. 4. 25. 16:22
ํ์ฌ ์์คํ
์์๋ ๋์ปค๋ฅผ ์ฌ์ฉํด ๋น๋ํ๊ณ ์ด๋ฏธ์ง๋ฅผ ์์ฑํด, EC2์ ๋ฐฐํฌํ๋ค.
์์ผ๋ก ์์์ด ๋ฐฐํฌ๊ฐ ๋ฐ๋ณต๋ ํ
๋ฐ, ์ด๋ฏธ์ง ์ฌ์ด์ฆ๋ฅผ ์ค์ด๊ณ ๋น๋์๊ฐ์ ๋จ์ถํ๋ ๊ฒ์ด ์๊ฐ๊ณผ ์ปดํจํ
์์์ ๋ญ๋น๋ฅผ ์ค์ผ ๊ฒ์ด๋ค!
ํ๊ฒฝ: java 21, ์คํ๋ง๋ถํธ3.4
๊ฒฐ๊ณผ์ ์ผ๋ก๋,
๋์ปค์ ์บ์ฑ์ ํ์ฉํด์ ์๊ฐ์ 65์ด->40์ด๋ก ์ฝ 35%๊ฐ์ ์ ํ ์ ์์๋ค!
1. ํ์ฌ ๋์ปคํ์ผ
# ๋น๋ ๋จ๊ณ
#๋ฒ ์ด์ค ์ด๋ฏธ์ง ์์ฑ. ๋์ปค ์ปจํ
์ด๋๋ฅผ ํน์ ์ด๊ธฐ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ธํ
.
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /back
COPY . .
RUN ./gradlew clean build
# ์คํ ๋จ๊ณ
FROM eclipse-temurin:21-jre
WORKDIR /back
COPY --from=builder /back/build/libs/weddy-0.0.1-SNAPSHOT.jar /back/weddy.jar
# ๋์ปค ์ปจํ
์ด๋๊ฐ 8080ํฌํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์์ ์ ์ธ
EXPOSE 8080
# ๋์ปค ์ปจํ
์ด๋๊ฐ ์์๋ ๋ ์คํ๋ ๊ธฐ๋ณธ ๋ช
๋ น์ด
CMD ["java", "-Dspring.profiles.active=local", "-jar", "weddy.jar"]
์ง๊ธ ๋์ปคํ์ผ์ ๋ณด๋ฉด ๋จ์ํ๋ค.
๋น๋ ํ ์ด๋ฏธ์ง ํฌ๊ธฐ๊ฐ 342MB์ ๋ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋์ปค๋ ๋ ์ด์ด๋ณ ์บ์ฑ์ ํ๋ค๊ณ ํ๋๋ฐ, ๊ทธ๋ฐ ๊ฒ๋ค์ ์ ์ฉํด๋ณด๊ณ ์ ํ๋ค.
2. ์ฐ์ ํฌ๊ธฐ ์ค์ด๊ธฐ
๋ฒ ์ด์ค ์ด๋ฏธ์ง๋ฅผ
FROM eclipse-temurin:21-jre
์์
FROM eclipse-temurin:21-jre-alpine
๋ก ๋ณ๊ฒฝํ์ฌ
์ฉ๋์ 342MB -> 260MB๋ก ์ค์๋ค!
์ฐธ๊ณ : https://doublejune.tistory.com/77
[๋์ปค] ๋์ปค ์ต์ ํ - ๋ฒ ์ด์ค ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์ค์ด๋ฉด ๋ฌด์กฐ๊ฑด ์ข์๊น?(alpine, musl libc, JNI)
ํ๋ก์ ํธ ๊ฐ๋ฐ์ ๋์ปค๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐํฌ๋ฅผ ํ๋ฉฐ, ๊ณผ์ ์ ์ข ๋ ์ต์ ํํ๊ณ ์ถ์ ์๊ฐ์ด ๋ค์๋ค. ์ค์ ์๋น์ค๋ฅผ ์ด์ํ๊ฒ ๋๋ค๋ฉด, ๋์ปค๋ก ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ ๋ฐฐํฌํ๋ ๊ณผ์ ์ด ์ ์์ด ๋ฐ๋ณต๋ ํ ๋ฐ,
doublejune.tistory.com
3. ๋ณธ๊ฒฉ์ ์ผ๋ก ๋น๋ ์๊ฐ ์ค์ด๊ธฐ - ๋ ์ด์ด ๋ถ๋ฆฌ
ํ์ฌ๋ ์์ค์ฝ๋๊ฐ ํ ์ค๋ง ์์ ๋๋๋ผ๋ ์์กด์ฑ์ ๋ค์ ๋ฐ์์ผํ๋ ๋ฌธ์ ๊ฐ ์๋ค.
๊ธฐ์กด ์ฝ๋์ COPY . . ๋ถ๋ถ์
ํ๋ก์ ํธ ์ ์ฒด๋ฅผ ๋ด๊ฐ builder๋ผ ์ด๋ฆ ๋ถ์ธ ์คํ ์ด์ง(ํ๋์ ๋ ๋ฆฝ๋ ์ด๋ฏธ์ง ๋จ์) ๋ด๋ถ๋ก ๋ณต์ฌํ๋ค.
๋ณต์ฌ๋ฅผ ํ ๋, ํ๋ก์ ํธ๊ฐ ์ด์ ๊ณผ ๋ฌ๋ผ์ง ๋ถ๋ถ์ด ์๋ค๋ฉด ๋์ปค ์บ์์ ์ ์ฅ๋ ๊ฒ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด ์ ์ฝ๋๋ค.
ํ์ง๋ง, ์์ค์ฝ๋ ํ ์ค ์ด๋ผ๋ ์์ ์ด ๋๋ค๋ฉด ์ ์ฒด๋ฅผ ๋ค์ ๋ณต์ฌํด์จ๋ค. ๊ทธ๋ฆฌ๊ณ , COPY . . ๋ ์ด์ด ์ดํ์ ๋ชจ๋ ๋ ์ด์ด๋ ๋ค์ ๋น๋๋๋ค.
์ฆ, ์์ค์ฝ๋๊ฐ ํ ์ค๋ง ์์ ๋๋๋ผ๋ ์์กด์ฑ์ ๋ค์ ๋ฐ์์ผํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋์, ๋ ์ด์ด๋ฅผ ๋ถ๋ฆฌํ๋ค.
์ :
#๋น๋ ๋จ๊ณ
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /back
COPY . .
RUN ./gradlew clean build
ํ :
# ๋น๋ ๋จ๊ณ
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /back
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN ./gradlew dependencies --no-daemon
COPY src src
RUN ./gradlew clean bootJar --no-daemon
์์กด์ฑ(gradle ๊ด๋ จ ํ์ผ)์ ๋จผ์ COPYํ๊ณ , ๋น๋ํ๋ค.
๊ทธ๋ฌ๋ฉด ๋์ปค์์๋ ์์ค์ฝ๋(src)๊ฐ ๋ณ๊ฒฝ๋์๋๋ผ๋, ์์กด์ฑ์ ๋ณ๊ฒฝ๋์ง ์์๊ธฐ ๋๋ฌธ์
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN ./gradlew dependencies --no-daemon
์์ ๋ชจ๋ ๋์ปค ์บ์ HIT ํ๊ฒ ๋๋ค.(=์์กด์ฑ์ ๋ค์ ๋ค์ด๋ก๋ํ ํ์ ์๋ค. ๊ธฐ์กด์ ๊ฒ์ ์ฌ์ฉํ๋ค.)
4. ์๊ฐ ์ข ๋ ์ค์ด๊ธฐ - spring boot์ jar ๋ ์ด์ด ๋ถ๋ฆฌ
์ฐ๋ฆฌ๋ ์์์ ๋ ์ด์ด๋ฅผ ์๊ฒ ์ชผ๊ฐค ์๋ก, ๋์ปค ์บ์ฑ์ ํตํด ํจ์จ์ฑ์ ๋์ผ ์ ์์์ ์์๋ค. (์๊ฒ ์ชผ๊ฐ๋ฉด, ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธํ๋ฉด ๋๋๊น)
๊ทธ๋์, Spring Boot ์๋ฒ๋ฅผ ๋น๋ํ ๊ฒฐ๊ณผ์ธ jarํ์ผ๋ ์ชผ๊ฐ๋ณธ๋ค.
Layered jar
: ๊ณ์ธตํ JAR. JAR ํ์ผ์ ๋ถ๋ฆฌํ์ฌ ๋ชจ๋ํํ ์ ์๋ ๊ธฐ์ .
Layerd jar๋ฅผ ์ฌ์ฉํ๋ฉด ์ฑ์ ๋ ๋น ๋ฅด๊ฒ ์์ํ ์ ์๋ค. ํ์ํ ๋ชจ๋๋ง ๋ก๋ํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ค์ด๋ค๊ณ , ๋ฐฐํฌ ๋ฐ ์ ๋ฐ์ดํธ๊ฐ ๋ ์ฌ์์ง๋ค.
*Layered JAR๋ Java 9๋ถํฐ ๋์
๋ ๋ชจ๋ ์์คํ
(Java Module System)์ ์ผ๋ถ ๊ธฐ๋ฅ์ด๋ค. ๋ฐ๋ผ์ Layered JAR๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด Java 9 ์ด์์ ๋ฒ์ ์ด ํ์ํ๋ค.
*๊ทธ๋ฆฌ๊ณ spring boot 2.3.0 ์ด์๋ถํฐ layer ๊ธฐ๋ฅ์ ์ง์ํ๋ค.
Layerd jar๋ ํฌ๊ฒ 4๊ฐ์ง ์์ญ์ผ๋ก ๊ตฌ๋ถ๋์ด์๋ค.
- application: ์ ํ๋ฆฌ์ผ์ด์
์์ค ์ฝ๋
- snapshot-dependencies: ํ๋ก์ ํธ ํด๋์ค ๊ฒฝ๋ก์ ์กด์ฌํ๋ ์ค๋
์ท ์ข
์์ฑ jar ํ์ผ
- spring-boot-loader: jar ๋ก๋์ ๋ฐ์ฒ
- dependencies: ํ๋ก์ ํธ ํด๋์ค ๊ฒฝ๋ก์ ์กด์ฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ jar ํ์ผ
์๋ก ๊ฐ์๋ก ๋ณ๊ฒฝ์ด ์ฆ์ ๋ ์ด์ด๋ค.
๋ณด๋ฉด, ๋์ปค์ ๋ ์ด์ด๊ตฌ์กฐ๊ฐ ๋ ์ค๋ฅธ๋ค.
๋์ปค๋ ๋ ์ด์ด๋ณ๋ก ์บ์๋ฅผ ๊ด๋ฆฌํ๋ค.
๊ทธ๋ฌ๋ ๋ณ๊ฒฝ์ด ์๋ ๋ ์ด์ด๋ ์บ์ฑ์ ๋นํ ์ ์๋๋ก Layered jar๋ฅผ ์ด์ฉํ๋ค.
# JAR ๋ ์ด์ด ์ถ์ถ ๋จ๊ณ
FROM eclipse-temurin:21-jre-alpine AS extractor
WORKDIR /back
COPY --from=builder /back/build/libs/weddy-0.0.1-SNAPSHOT.jar weddy.jar
RUN java -Djarmode=layertools -jar weddy.jar extract
# ์คํ ๋จ๊ณ
FROM eclipse-temurin:21-jre-alpine
WORKDIR /back
COPY --from=extractor /back/dependencies/ ./
COPY --from=extractor /back/spring-boot-loader/ ./
COPY --from=extractor /back/snapshot-dependencies/ ./
COPY --from=extractor /back/application/ ./
์๋ ๋ณ๊ฒฝ ํ ์ฝ๋๋ค.
RUN java -Djarmode=layertools -jar weddy.jar extract
๋ฅผ ํตํด 4๊ฐ์ ๋ถ๋ฆฌ๋ ๋ ์ด์ด๊ฐ ๋ง๋ค์ด์ง๋ค.
๊ทธ ํ,
FROM eclipse-temurin:21-jre-alpine
WORKDIR /back
COPY --from=extractor /back/dependencies/ ./
COPY --from=extractor /back/spring-boot-loader/ ./
COPY --from=extractor /back/snapshot-dependencies/ ./
COPY --from=extractor /back/application/ ./
์ด๋ ๊ฒ ์ ๋ณ๊ฒฝ๋์ง ์๋ ๋ ์ด์ด ๋ถํฐ COPYํ๋ค.
๋์ปค๋ ํ์ ๋ ์ด์ด๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ, ๊ทธ ์์ ๋ ์ด์ด๋ถํฐ๋ ์ ๋ถ ๋ค์ ์์ฑ(์ด๊ธฐํ)ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ณ๊ฒฝ์ด ์ ์ ๋ ์ด์ด๋ถํฐ ์์์ผ ์บ์ฑ์ ์ ๋นํ ์ ์๋ค.
5. ์ต์ข ์์ฑ๋ณธ
# ๋น๋ ๋จ๊ณ
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /back
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
RUN ./gradlew dependencies --no-daemon
COPY src src
RUN ./gradlew clean bootJar --no-daemon
# JAR ๋ ์ด์ด ์ถ์ถ ๋จ๊ณ
FROM eclipse-temurin:21-jre-alpine AS extractor
WORKDIR /back
COPY --from=builder /back/build/libs/weddy-0.0.1-SNAPSHOT.jar weddy.jar
RUN java -Djarmode=layertools -jar weddy.jar extract
# ์คํ ๋จ๊ณ
FROM eclipse-temurin:21-jre-alpine
WORKDIR /back
COPY --from=extractor /back/dependencies/ ./
COPY --from=extractor /back/spring-boot-loader/ ./
COPY --from=extractor /back/snapshot-dependencies/ ./
COPY --from=extractor /back/application/ ./
# ๋์ปค ์ปจํ
์ด๋๊ฐ 8080ํฌํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์์ ์ ์ธ
EXPOSE 8080
# ๋์ปค ์ปจํ
์ด๋๊ฐ ์์๋ ๋ ์คํ๋ ๊ณ ์ ๋ช
๋ น์ด
ENTRYPOINT ["java", "-Dspring.profiles.active=local", "org.springframework.boot.loader.launch.JarLauncher"]
๊ฒฐ๊ณผ์ ์ผ๋ก๋,
๋์ปค์ ์บ์ฑ์ ํ์ฉํด์ ์๊ฐ์ 65์ด->40์ด๋ก ์ฝ 35%๊ฐ์ ์ ํ ์ ์์๋ค!
- ๋ณ๊ฒฝ ์
- ๋ณ๊ฒฝ ํ
์ถ๊ฐ๋ก
- gradle build ๋์ bootjar๋ฅผ ์ฌ์ฉํด์ ์๊ฐ์ ๋จ์ถํ๋ค.
: build๋ ๋ด๋ถ ๋์์ด ๋ ๋ง๋ค. test์ฝ๋ ์คํ, ํ๋ก๋์ ์ํฐํฉํธ ์์ฑ ๋ฐ ๋ฌธ์ ์์ฑ์ ํฌํจํ ์ฌ๋ฌ๊ฐ์ง๊ฐ ํฌํจ๋๋ค. bootjar๋ ๋จ์ํ ํ๋ก์ ํธ์ jarํ์ผ๋ง์ ๋ง๋๋๋ฐ ๋ชฉ์ ์ ๊ฐ์ง๊ณ ์๋ค.
- bootjar์ clean bootjar๋ฅผ ํ๋ค. ์๊ฐ์ ์ข ๋ ๊ฑธ๋ฆด ์ ์์ง๋ง.
clean์ /build์ ์๋๋น๋ ๊ฒฐ๊ณผ๋ฌผ(์ปดํ์ผ ๊ฒฐ๊ณผ๋ฌผ, ํด๋์คํ์ผ๋ฑ) ๋ชจ๋ ๋น๋ ์ฐ์ถ๋ฌผ์ ์ญ์ ํ๋ค. clean์ ์ฌ์ฉํด ํน์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ๋ฅผ ์๋ฐฉํ๊ณ ์ ํ๋ค. ex. ์ค๋๋ ํด๋์คํ์ผ ์ ์ง ๋ฑ ๋ถ์ผ์น ๋ฌธ์ .
์ฐธ์กฐ
Gradle, Layered Jar ๊ทธ๋ฆฌ๊ณ Dockerbuild ์ต์ ํ
ํ๋ก์ ํธ ๋น๋ ์๋๊ฐ ๋ต๋ตํ๋ค๋ฉด? Maven์์ Gradle๋ก ๋น๋ํด์ ๋ณ๊ฒฝํ๋ฉด ์ข์ ์ด์ . ๊ทธ๋ฆฌ๊ณ Docker build ์ต์ ํํ๊ธฐ!
velog.io
[Spring] bootjar๊ณผ ๊ทธ๋ฅ build์ ์ฐจ์ด
ํ๋ก์ ํธ ๋ฐฐํฌ๋ฅผ ์งํํ๊ธฐ ์ํด ๋น๋๋ฅผ ์งํํ๋ ์์ค ์๋์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋จ๋ฉฐ ๋น๋๊ฐ ์งํ๋์ง ์์๋ค. ๊ทธ๋์ ๋ฐฑ์๋ ์ฑํฐ๋ฅผ ๋งก๊ณ ์๋ ํ์์๊ฒ ๋ฌผ์ด๋ณด๋ ./gradlew bootjar ๋ก ๋น๋๋ฅผ ํด๋ณด๋๋ค.
velog.io