Spring Boot, Docker 멀티 스테이지 빌드하기

이재훈·2024년 9월 19일

계기

Docker 의 멀티 스테이지 빌드가 이미지 경량화의 효과가 있었다. 그리고 예전에 팀 프로젝트 했을때 테스크 코드 때문에 빌드 속도가 매우 느렸다. 그래서 이번 기회에 Spring Boot 프로젝트의 도커 이미지 빌드 과정을 개선해보려고 한다.

계획

Spring Boot 프로젝트를 실행하는 과정은 다음과 같다.
1. Gradle 기반 빌드
2. JDK 기반 실행

# step 1: Build Stage  
FROM gradle:jdk17-alpine AS build  
WORKDIR /home/app  
COPY ./ ./  
RUN ./gradlew bootJar  
  
# step 2: Run Stage  
FROM openjdk:17-alpine AS run  
WORKDIR /home/app  
COPY --from=build /home/app/build/libs/*.jar app.jar  
ENTRYPOINT ["java", "-jar", "app.jar"]
docker build -t spring-boot-app-multi-stage .

처음에는 build 를 쓸까 고민했지만 빌드 과정은 test 과정을 내포하고 있어 시간이 많이 걸린다. 그리고 실제 배포 이전에 test 과정을 거친결과만 올리게 될 것이므로 빠르게 배포하려고 한다.

gradle 에서 build 과정은 아래와 같다.

:compileJava SKIPPED
:processResources SKIPPED
:classes SKIPPED
:resolveMainClassName SKIPPED
:bootJar SKIPPED
:jar SKIPPED
:assemble SKIPPED
:compileTestJava SKIPPED
:processTestResources SKIPPED
:testClasses SKIPPED
:test SKIPPED
:check SKIPPED
:build SKIPPED

bootJar 은 test 이전까지의 과정만 거치기 때문에 빠른 빌드가 가능하다.

:compileJava SKIPPED
:processResources SKIPPED
:classes SKIPPED
:resolveMainClassName SKIPPED
:bootJar SKIPPED

싱글 스테이지 빌드와 비교

이전에는 Java 기반 이미지에서 효능감을 확인하려고 한다.

# step 1: Single Stagae Build  
FROM openjdk:17-alpine  
WORKDIR /home/app  
COPY ./ ./  
RUN ./gradlew bootJar  
COPY *.jar app.jar  
ENTRYPOINT ["java", "-jar", "app.jar"]
docker build -t spring-boot-app-single-stage .

실행 결과

스테이지별 용량 차이 확인

싱글 스테이지 빌드와 멀티 스테이지 빌드의 용량 차이가 2배 가까이 나는 것을 확인할 수 있다. 빌드 시간은 각각 약 60초와 77초로 멀티 스테이지 빌드에서 시간이 더 걸린다.

0개의 댓글