들어가며
스프링 프로젝트에 Docker를 세팅했는데, Docker 도 최적화가 가능할까?라는 생각에 검색하던 중
Docker Cache를 발견하게 되었습니다.
Docker를 이용한 스프링 서버의 빌드 속도 최적화 과정
- 스프링 서버 Docker로 세팅: 스프링 서버를 Docker 컨테이너로 설정합니다.
- Dockerfile 작성: Dockerfile을 작성하고, 각자의 요구에 맞게 수정합니다.
- 캐시 사용 Dockerfile: Docker 캐시가 작동하도록 Dockerfile을 최적화합니다.
- 최적화된 Docker 빌드: 최적화된 Dockerfile을 사용하여 빌드 과정을 빠르게 수행합니다.
Docker Layer
Docker Cache를 이해하기 전에 먼저 `Docker의 Layer`에 대해 먼저 알아야 합니다.
Docker는 image를 통해 애플리케이션을 실행하는데, 이 때 내부적으로 image에서 Layer를 쌓으면서 실행됩니다.
즉, container를 실행하면, image를 통해 base layer들이 쌓이면 그 위에서 container layer로 실행되는 것입니다.
Dockerfile
Dockerfile이란 애플리케이션을 Image로 만들기 위해 작성하는 설정 파일입니다.
즉, Dockerfile 의 내용으로 Docker Image 가 어떤식으로 구성되어 있는지 알 수 있습니다.
매번 애플리케이션을 실행할 때마다 패키지를 설치하고 환경설정하는 과정을 40번만 반복해도 번거롭게 느껴질 텐데,
Dockerfile을 통해서 실행할 때 필요한 패키지, 명령어, 환경변수 등을 미리 기록해 둘 수 있습니다.
이런 식으로 애플리케이션의 빌드 및 배포를 유연하게 자동화할 수 있게끔 하려는 것이 `Dockerfile 작성의 목적`입니다.
그럼 `Docker에서 캐시가 되는 기준`은 무엇일까요?
Docker에서는 "ADD, COPY"를 제외하면 String의 형태만 확인하고, "ADD, COPY"는 String + 내용의 변화까지 확인해서 Cache의 적용 기준을 정합니다.
예를 들면, 위의 예시에서 FROM, ARG같은 경우는 명령어의 형태만 변하지 않으면 Docker cache를 적용하지만, COPY같은 경우 {JAR_FILE}의 내용이 바뀌었으면 같은 명령어라도 cache를 적용할 수 없습니다.
Dockerfile 예시
FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
Dockerfile 위치
Dockerfile의 위치는 `빌드할 Application이 위치한 모듈의 루트 디렉토리`에 두어야 합니다.
-> JAR_FILE=build/libs/*.jar 경로 때문
docker build --platform linux/amd64 -t springboot-app .
Dockerfile 이 위치한 루트 디렉토리에서 위 커맨드를 실행합니다.
`--platform linux/amd64 옵션`을 붙여야 하는 이유는 베이스 이미지를 openjdk:17-alpine로 설정했기 때문입니다.
alpine은 linux/amd64 아키텍쳐에서 작동하도록 만들어진 빠르고 가벼운 이미지라는 컨셉입니다.
해당 옵션이 없다면 무한로딩을 경험할 수 있습니다.
자 이제 Dockerfile로 빌드한 이미지가 생성되었습니다.
성능 측정
애플리케이션과테스트를 함께 빌드시켜서 성능을 측정해보겠습니다.
도커 캐시 X
gradle 첫 빌드 후에 연달아서 빌드했습니다.
-> 두 번째 빌드 효과는 약 `10%`
도커 캐시 O
gradle 첫 빌드 후에 연달아서 빌드했습니다.
-> 두 번째 빌드 효과는 약 `50%`
마치며
Docker Cache를 적용한다면 첫 빌드 후에 이어지는 빌드에서 감소 폭이 확실하게 컸음을 확인했습니다. 이는 반복되는 개발에서 많은 시간을 아껴줄 것입니다.
참고로, 멀티모듈 프로젝트에서는 각 모듈 간의 의존성 때문에 코드 변경 시 여러 모듈이 다시 빌드되어야 하므로 캐시의 효과가 상대적으로 작습니다.
반면, 단일모듈 프로젝트에서는 변경 사항이 적은 레이어만 다시 빌드되므로 캐시의 효과가 더욱 큽니다. 따라서 단일모듈 프로젝트에서는Docker Cache를 도입할 가치가 충분합니다.
참고한 곳
https://potato-yong.tistory.com/111
https://simmigyeong.tistory.com/59
'Web' 카테고리의 다른 글
WEB2 - JavaScript 핵심 정리 (by 생활코딩) (0) | 2022.01.28 |
---|---|
WEB2 - CSS 핵심 정리 (by.생활코딩) (0) | 2022.01.20 |
WEB1 - HTML & Internet 핵심 정리 (by.생활코딩) (0) | 2022.01.13 |