현재 문제
도커 이미지 사이즈가 점점 커지고 있다..!
서비스를 배포할 때 Amazon 에서 관리하는 이미지를 사용하고 있었다. 이미지 용량이 500MB를 넘어가면서, 무거운 이미지가 배포 속도를 느리게 만드는 건 아닐까? 하는 생각에 배포 과정을 개선해보기로 했다.
시도 과정
흔히들 하는 실수중의 하나가 자바 런타임용 컨테이너를 만들때, 컴파일러가 포함된 JDK 환경을 사용한다는 것이다. 보통 자바 런타임은 JDK 없이 JRE 만 있어도 충분하다.
출처: https://bcho.tistory.com/1356 [조대협의 블로그:티스토리]
1. 멀티 스테이지 빌드 도입
FROM gradle:8.9-jdk21-alpine AS build
WORKDIR /app
COPY . .
RUN gradle build -x test
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
ARG SPRING_PROFILES_ACTIVE=dev
ENV SPRING_PROFILES_ACTIVE=$SPRING_PROFILES_ACTIVE
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "app.jar"]
빌드할 때는 JDK가 필요하지만, 실행에는 JRE만 있어도 된다. 최종 Docker 이미지에는 JDK를 포함하지 않도록 구성했다.
2. 경량 런타임 이미지 사용
가장 경량화 이점이 큰 eclipse-temurin:21-jre-alpine
기반 이미지를 선택했다.
기존 574MB → 약 280MB로 약 50% 경량화할 수 있었다.
결과
경량화는 했지만.. 배포 속도를 줄이지는 못했다.
🤔 왜 일까
기존 서버는 캐시가 있어서 pull 속도 차이가 크지 않다.
배포 속도의 병목은 이미지 용량이 아니라 애플리케이션 시작 시간에 있다. 실제로 gradlew build와 새로운 docker를 띄우고 헬스체크까지 하는 데 각각 1분 이상을 사용하고 있었다.
따라서 배포 속도를 개선하기 위해선 Gradle 캐시 + 빌드 최적화 과정을 거쳐야 한다.
그럼.. 난 시간을 버린걸까?
No !!!!
이미지 경량화를 통해
- 이미지 사이즈 574MB → 약 280MB로 약 50% 경량화
- 불필요한 패키지를 줄여 보안 강화
의 이점을 얻을 수 있었다.
앞으로의 계획
기존 서버는 캐시가 있어서 pull 속도 차이가 크지 않지만, 새로운 서버를 띄워서 오토스케일링을 하고자 할 때 속도 차이가 커진다. 따라서 오토스케일링이나 신규 서버를 띄우는 환경이라면 시도해봐도 좋을 것 같다.
아직 배포 속도를 개선하고 싶은 욕심을 버리지 못했다.. 우리에게 소중한 시간이니까.
속도를 개선할 수 있는 캐시 최적화를 공부하고 적용해봐야겠다 !!
(3탄으로 돌아올게요)