개요
현재 진행하고 있는 프로젝트에서 서버 애플리케이션을 Docker 이미지로 관리하고 있다.
Spring Boot 기반의 프로젝트로, Dockerfile을 작성해 이미지를 빌드하고 이를 컨테이너로 실행한다.
하지만 기존 방식으로 생성된 이미지의 크기가 상당히 커,
1. 네트워크 전송 비용 증가
2. 빌드/배포 시간 증가
3. 테스트 및 로컬 실행 시 부담
과 같은 문제들이 발생했다.
이를 해결하기 위해 Dockerfile을 리팩토링하고 이미지 경량화 작업을 진행하게 되었다.
아래는 그 과정을 기록한 내용이다.
기존 Dockerfile 구조
기존 Dockerfile은 단일 스테이지로 구성되어 있어 다음과 같은 단점이 있었다
1. 빌드 도구, 소스 코드, 테스트 리소스 등 불필요한 파일까지 이미지에 포함됨
2. 불필요한 의존 패키지로 인해 용량 증가
3. base image가 비교적 무거운 openjdk 계열
Docker 이미지는 레이어(layer) 기반 구조를 가지고 있고, 각 명령어(COPY, RUN 등)마다 새로운 레이어가 생성되기 때문에
최적화된 레이어 분리가 필요하다.
기존 Dockerfile
# Build stage
FROM openjdk:21-jdk
CMD ["./gradlew", "clean", "build"]
# 환경변수 설정
ENV CUSTOM_NAME default
# jar 파일 위치를 변수로 설정
ARG JAR_FILE=build/libs/*.jar
# jar 파일을 컨테이너 내부에 복사
COPY ${JAR_FILE} app.jar
# 외부 호스트 8080 포트로 노출
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
경량화 이미지 사용
가장 단순하면서 큰 효과를 볼 수 있는 방법이다.
base image를 바꾸는 것 만으로도 꽤 많은 용량을 줄일 수 있다.
물론 기존 사용하던 이미지와 비교하여 없는 기능이 있기 때문에,
미리 프로젝트에서 사용하는 의존성에 대해 알아보고 반영하는 것이 좋다.
# Build stage
FROM eclipse-temurin:21-jdk
CMD ["./gradlew", "clean", "build"]
# 환경변수 설정
ENV CUSTOM_NAME default
# jar 파일 위치를 변수로 설정
ARG JAR_FILE=build/libs/*.jar
# jar 파일을 컨테이너 내부에 복사
COPY ${JAR_FILE} app.jar
# 외부 호스트 8080 포트로 노출
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
멀티 스테이지 분리
실제 애플리케이션을 실행할 때는 빌드 도구(Gradle, Maven 등)가 필요하지 않다.
하지만 단일 스테이지로 Dockerfile을 작성할 경우 빌드 도구까지 이미지에 포함되어버린다.
멀티 스테이지 빌드를 활용하면 빌드 단계와 실행 단계를 분리하여
최소한의 실행 환경만 이미지에 포함시킬 수 있다.
# ======== 1단계: Build Stage ========
FROM gradle:8.5-jdk21 AS builder
WORKDIR /app
COPY . .
# 캐시를 활용한 build 속도 최적화
RUN gradle clean build -x test
# ======== 2단계: Run Stage ========
FROM eclipse-temurin:21-jre as runtime
WORKDIR /app
# 빌드 결과 JAR 복사
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
결과
처음 이미지 크기는 약 680MB였지만, 경량화 과정을 거치고 182MB로 약 73% 감소하게 되었다.
이처럼 멀티 스테이지 빌드와 경량화된 base image를 활용하면 이미지를 보다 가볍고 효율적으로 관리할 수 있다.
Docker 이미지를 작성할 때 단순히 작동만 되는 구조보다 빌드 속도와 운영 효율성을 고려하는 것이 중요하다.
프로젝트 초기부터 Dockerfile 설계를 잘 해두면 CI/CD 파이프라인과 클라우드 환경에서 큰 장점을 가져올 수 있다.
'Docker, Container' 카테고리의 다른 글
[Docker] 컨테이너 timezone 변경 (2) | 2025.04.03 |
---|---|
[Linux] Docker, Docker Compose 설치 (0) | 2025.03.26 |