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초로 멀티 스테이지 빌드에서 시간이 더 걸린다.