[Docker] Springboot 이미지 최적화

2025. 3. 28. 04:06·Docker, Container

개요

현재 진행하고 있는 프로젝트에서 서버 애플리케이션을 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
'Docker, Container' 카테고리의 다른 글
  • [Docker] 컨테이너 timezone 변경
  • [Linux] Docker, Docker Compose 설치
코딩 못하는 감자
코딩 못하는 감자
  • 코딩 못하는 감자
    코딩 못하는 감자의 기록
    코딩 못하는 감자
  • 전체
    오늘
    어제
    • 분류 전체보기 (91)
      • Kubernetes (10)
      • Github Action (1)
      • Docker, Container (3)
      • Springboot (26)
      • Baekjoon (4)
      • 명품 운영체제 (9)
      • 데이터베이스 (2)
      • JSP (3)
      • 안드로이드프로그래밍 (1)
      • 미니프로젝트 (1)
      • 용어정리 (0)
      • 소프트웨어공학 (3)
      • 운영체제 (2)
      • Flutter (0)
      • Git (1)
      • HTTP (0)
      • RAG (1)
      • Database (2)
      • FastAPI (1)
      • Elasticsearch (7)
      • Redis (0)
      • JPA (5)
      • Linux (1)
      • MCP (1)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    fuzziness
    Dockerfile
    elasticsearch ngram
    SpringBoot
    엘라스틱서치 인덱스 복사
    응답 로그
    엘라스틱서치 인덱스
    elasticsearch 커스텀분석기
    mcp #model context protocol #claude desktop #mcp claude연동 #claude 파일 시스템 연동
    elasticsearch analyzer
  • hELLO· Designed By정상우.v4.10.3
코딩 못하는 감자
[Docker] Springboot 이미지 최적화
상단으로

티스토리툴바