- 일반적으로 spring boot로 docker image를 만들때 다음과 같이 dockerFile 을 작성한다.
FROM openjdk:8-jdk-alpine
EXPOSE 8080
ARG JAR_FILE=target/demo-app-1.0.0.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- Docker 이미지는 레이어로 빌드된다.
- 도커는 효과적인 배포를 위해서 레이어별로 캐시를 해서, 변경이 없는 레이어에 대해서는 다시 pull/push를 하지 않는다.
- Spring Boot fat jar의 특성은 모든 애플리케이션 코드와 3rd party 라이브러리가 single layer에 배치되는 것 이다.
- 그 영향으로 한 줄의 코드 만 변경하더라도 전체 레이어를 다시 빌드 한다.
- 보통 배포를 진행할때 3rd party 라이브러리가 수정되는 경우는 거의 없고, 소스 코드 수정 때문에 배포를 진행하는 경우가 많다.
- single-layer 는 직관적이고 이해하기가 쉽지만 어플리케이션 소스만 변경 되더라도 전체 jar를 다시 만든다.
- 이는 컨테이너화 된 환경에서 시작 시간에 영향을 미칠 수 있다.
→ 소스 코드 수정 때문에 배포가 진행이 된다면 레이어를 세분화로 나눠서 변경이 없는 레이어는 캐시를 하고 변경 되는 소스코드만 배포하는게 효과적이다.
(https://dzone.com/articles/optimizing-spring-boot-application-for-docker)
사전 준비
- layed jar는 일반 부트 패키지 jar와 동일한 레이아웃을 사용하지만 각 계층을 설명하는 추가 메타 데이터 파일을 포함한다.
- layed jar 기능을 사용하려면 build.grade 에 다음 설정을 추가 해야한다.
bootJar {
layered()
}
- layer는 다음과 같이 분리 된다.
. dependencies : 버전에 스냅샷이 포함되어 있지 않은 모든 dependency
. spring-boot-loader : jar loader classes 용
. snapshot-dependencies : 버전에 스냅샷이 포함되어 있는 모든 dependency
. application : 어플리케이션 클래스와 리소스
기존 DockerFile
FROM docker-java8-debian:master
WORKDIR /app
COPY run.sh ./
COPY application.jar ./
EXPOSE 9060
ENTRYPOINT ["/bin/sh", "run.sh"]
- 간단히 설명 하자면 미리 만들어놓은 base image(From에 정의 되어 있음)
- run.sh 과 application.jar 를 복사 한다음에 미리 정의 되있는 run.sh로 실행을 한다.
- fat jar일때 소스 변경시 되었을때, 전체 변경(80.8mb)이 일어난걸 확인 할수 있다. (Jar 파일을 copy해서 run.sh에서 java로 실행)
- docker history를 보면 image를 어떻게 만들었는지 확인 할 수 있다.
→ COPY application.jar ./
수정된 DockerFile
- 먼저 base image에서 jar를 copy 해서 -Djarmode=;ayertools로 폴더를 추출 해야한다.
- 만약 gradle에 build 옵션을 추가 하지 않았으면 해당 명령어는 에러를 반환한다.
FROM docker-java8-debian:master as builder
WORKDIR /app
COPY application.jar ./
RUN java -Djarmode=layertools -jar application.jar extract
FROM docker-java8-debian:master
WORKDIR /app
COPY run.sh ./
COPY --from=builder app/dependencies/ ./
COPY --from=builder app/snapshot-dependencies/ ./
COPY --from=builder app/spring-boot-loader/ ./
COPY --from=builder app/application/ ./
EXPOSE 9060
ENTRYPOINT ["/bin/sh", "run.sh"]
- 소스에 해당하는 부분(10.6mb)만 변경이 일어난걸 확인 할 수 있다.
- 다른 부분은 수정하지 않고 소스만 수정 해서 Docker 빌드시 다른 레이어들은 캐시를 사용하는것 확인
Window에서 테스트 하는 방법도 있는데....
- uild 해서 jar 파일을 만든다.
- 해당 폴더에서 다음명령어로 layer를 만든다.
→ java -Djarmode=layertools -jar {jar Name} extract
- dependencies, snapshot-dependencies, spring-boot-loader, application 안에 있는 폴더를 상위폴더로 복사한다.
→ DockerFile에 있는 copy와 동일한 명령 수행.
COPY --from=builder dependencies/ ./
COPY --from=builder snapshot-dependencies/ ./
COPY --from=builder spring-boot-loader/ ./
COPY --from=builder application/ ./
- java org.springframework.boot.loader.JarLauncher 명령어로 실행한다.
참고 사이트 : https://www.baeldung.com/spring-boot-docker-images
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/gradle-plugin/reference/html/#packaging-layered-jars
'개발' 카테고리의 다른 글
docker base image Debian 과 alpine - 효율적인 도커 이미지 (0) | 2021.06.19 |
---|---|
Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@3900e5a6 (No operations allowed after connection closed.). Possibly consider using a shorter maxLifetime value. (0) | 2021.06.15 |
spring cloud stream 적용기 (1) | 2020.01.10 |
HTTP 완벽 가이드 - http 메시지 (0) | 2019.09.09 |
http 완벽 가이드 - URL 과 리소스 (0) | 2019.09.08 |