코딩과로그
도커 이미지 빌드 시 캐시 활용 (feat: Image Layer) 본문
# 해당 문서는 node.js의 package.json의 활용을 안다는 전제하에 적었습니다.
깃허브 경로: https://github.com/SangYunLeee/simple-node-js-server-for-docker-study.git
아래는 Dockerfile 이다.
# Dockerfile
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
여기서 도커 이미지를 재 빌드 시 캐시를 활용할 여지가 있는 부분이 있을까?
있다!!
캐시를 활용한 결과를 먼저 말하자면,
3.6초 걸리던 빌드가 0.7초로 약 80% 빌드 시간이 감소되었다.
어떻게 이게 가능했을까?
우선 도커 이미지 빌드 시 Image Layer 라는 개념을 알아야 한다.
도커 이미지가 빌드될 때에는 Dockerfile 를 사용하는데,
Dockerfile 의 실행 명령어 하나하나가 하나의 layer가 된다.
위의 이미지 예시는 각각의 명령어가 하나의 레이어가 되는 것을 보여준다.
내가 만든 Dockerfile은 다음과 같은 레이어가 된다.
# Dockerfile
# layer 1
FROM node
# layer 2
WORKDIR /app
# layer 3
COPY . /app
# layer 4
RUN npm install
# EXPOSE는 단순 문서용이라 layer가 아니다.
EXPOSE 80
# CMD는 컨테이너가 실행 시 동작하기에 이미지 빌드 시 layer에 포함되지 않는다.
CMD ["node", "server.js"]
이미지를 한번 빌드 해놓으면 다시 빌드할 때에는 이전에 빌드할 때 사용한 캐시를 활용한다.
만약 각 레이어가 이전에 빌드하여 캐시된 레이어와 동일하다면 캐시를 가져와서 사용한다.
아래는 빌드 한 후 다시 재빌드했을 때 나온 결과이다. CACHED 라는 표시를 볼 수 있다.
그런데 캐시를 활용하지 못하는 레이어가 있을 수 있다.
COPY 명령어의 경우, 복사하려는 대상이 변경되었다면 기존 캐시되었던 값과 달라졌기 때문에 캐시값을 사용할 수 없다.
따라서 COPY . /app 명령어에서 "." 부분인 로컬 호스트상의 복사 대상이 변경되었다면 캐시를 재활용할 수 없을 것이다("/app" 부분도 동일할 것으로 예상됨).
캐쉬된 값을 사용할 수 없기에 시간이 복사를 완전히 다 하기에 시간이 오래 걸린다.
더불어 COPY 이후의 레이어 또한 COPY 레이어에서 변경된 사항때문에 이후의 레이어들 또한 캐시값을 사용할 수 없다 (변경된 레이어에 의해서 다음의 레이어 명령이 영향을 받기 때문이다.).
즉 아래와 같이 layer 3 만 변경되었는데 layer 4까지 Cash 값을 사용하지 못하는 현상이 발생한다.
# Dockerfile
# layer 1 <- Cashed됨
FROM node
# layer 2 <- Cashed됨
WORKDIR /app
# layer 3 <- 소스가 바뀌어서 Cash값을 사용하지 못함
COPY . /app
# layer 4 <- 이전 layer가 바뀌어서 cash값을 사용하지 못함
RUN npm install
...
따라서 layer3, 4까지 모두 다시 빌드해야되어 시간이 오래 걸린다.
결론적으로 아래와 같이 Dockerfile 을 수정하였다.
# 캐시 활용 가능
FROM node
# 캐시 활용 가능
WORKDIR /app
# 캐시 활용 가능
COPY package.json /app
# 캐시 활용 가능
RUN npm install
# 캐시 활용 불가 <- 오로지 이 부분만 캐시 비활용
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
위와 같이 변경하여 RUN npm install 은 캐시값을 활용할 수 있게 되었다. 따라서 빌드 시간이 획기적으로 단축될 수 있었다.
ref:
https://www.udemy.com/course/docker-kubernetes-the-practical-guide/learn/lecture/22166800#overview
'Docker' 카테고리의 다른 글
[기록용] 도커 네트워크 연결 (0) | 2023.03.31 |
---|---|
[기록용] 도커 환경변수 설정하는 다양한 방법 (ENV, ARG) (0) | 2023.03.30 |
DockerFile 문법 해석 (0) | 2023.03.29 |
도커 데스크탑과 도커 엔진의 차이점 및 도커 데스크탑의 장점 (0) | 2023.03.28 |
도커 명령어 모음 (정리 중) (0) | 2023.03.20 |