-
Maven, Gradle 도커에서 빌드과정 최적화하기, Maven편Computer Science/Java 2025. 6. 1. 16:15
Docker 레이어를 활용한 Maven 빌드 최적화 전략
Maven은 로컬에서 빌드할 때 보통 .m2 폴더를 활용해 의존성 파일들을 로컬에 저장하고, 이를 캐시로 활용함으로써 빌드 시 매번 의존성을 다시 다운로드하지 않는다. Docker 환경에서도 동일하게 의존성이 설치된 .m2 폴더를 불러와서 캐싱하는 방법을 소개해보려고 한다. Dockerfile에서 pom.xml의 의존성 설치 부분과 빌드 부분을 분리해 복사하면, Docker의 레이어 캐시 기능 만으로도 빌드 시간을 크게 줄일 수 있다. 오늘은 이 방법에 대해 알아볼 예정이다.
Dockerfile: 변경 가능성이 낮은 것부터 COPY
Dockerfile에서 레이어 캐시를 활용하여 속도를 줄일 수 있는데 이 글에서는 maven 캐싱이 주된 내용이기 때문에 간략히 핵심만 적어보려고 한다. Docker는 명령어 단위로 이미지를 레이어(layer)로 생성하고, 동일한 명령어 및 입력이 들어올 경우 해당 레이어를 캐시에서 재사용한다. 이 원리를 활용해 Maven 프로젝트의 의존성 설치 부분과 실제 빌드 부분을 분리하면, 의존성 레이어는 변경되지 않고 재사용되고, 코드가 바뀌어도 의존성은 다시 다운로드하지 않아도 된다.
Dockerfile 정리
전
FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /build COPY pom.xml . COPY src ./src # 실제 빌드 명령어 RUN mvn package -DskipTests FROM eclipse-temurin:17-jdk WORKDIR /app COPY --from=builder /build/target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
후
FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /build COPY pom.xml . # maven 의존성 설치 명령어 RUN mvn dependency:go-offline -B COPY src ./src # 실제 빌드 명령어 RUN mvn package -DskipTests FROM eclipse-temurin:17-jdk WORKDIR /app COPY --from=builder /build/target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
이렇게 RUN mvn dependency:go-offline 한줄만 추가함으로써 의존성 설치 과정을 분리할 수 있다. pom.xml이 변경되지 않는 한 RUN mvn dependency:go-offline 명령은 캐시에서 재사용된다. 이는 .m2를 공유하지 않더라도 의존성 재다운로드를 피할 수 있게 해준다.
(추가적으로 위 이미지처럼 멀티 스테이지 빌드를 활용하면, 최종 이미지에는 Maven과 빌드 결과 외의 소스나 불필요한 파일이 포함되지 않아 이미지 용량도 줄일 수 있다.)
정리
.m2 캐시 공유 없이도, Docker 레이어 구조를 잘 설계하면 Maven의 의존성 다운로드 단계는 반복되지 않고 캐시로 대체될 수 있다. 특히 CI/CD 환경에서는 매번 새로운 환경에서 빌드가 이루어지므로, 이런 구조를 갖춘 Dockerfile은 지속적인 빌드 속도 개선에 큰 영향을 미친다.
또한, 번외로 일반적인 CICD 환경이 아닌, 도커 레이어 캐시를 활용하지 않고 Buildkit을 활용하여 마운트시킬 수 있는 환경이라면RUN '--mount=type=cache,target=/root/.m2'
이 방법 을 통해 Maven의 .m2 디렉토리를 직접 캐싱하는 방법도 유효하다. 위와 같은 방법들로 Docker 자체의 레이어 캐시 또는 BuildKit 캐시 mount 기능만으로 안정적인 빌드 속도 향상이 가능하다.
주의할 점
pom.xml에서 nexus 등을 통해 내부 모듈을 사용하고 있는 환경이라면, 실제 모듈의 내용이 바뀌었는데 pom.xml이 같은 파일이라면 pom.xml이 바뀌지 않았기 때문에 캐싱이 되어 빌드된 결과물이 변경이 안된 것 처럼 볼 수 있다. 따라서 내부모듈이 바뀐다면 버전을 새로 찍는 등의 방법을 통해 pom.xml을 바꾸는 것을 권장한다.
참고
'Computer Science > Java' 카테고리의 다른 글
Maven, Gradle 도커에서 빌드과정 최적화하기, Gradle편 (0) 2025.06.01