본 게시글은 유데미(udemy.com)의 < 【한글자막】 Docker & Kubernetes : 실전 가이드 > (Maximilian Schwarzmüller) 강의를 수강한 후 내용을 정리한 것입니다.
도커 컨테이너에 담긴 소스 코드의 일부를 수정하고 싶다.
이 코드를 수정한 다음 컨테이너에 새로 반영하고 싶었기 때문에 컨테이너를 중단하고 다시 시작했다.
어라, 그런데 여전히 아까랑 똑같은 결과다. 왜 그런 걸까?
그 이유는, 도커 image는 소스코드의 스냅샷(snapshot)을 찍는 것과 같기 때문이다.
즉 image는 한번 빌드한 이후로는 기본적으로 외부에서 더 이상 바꿀 수 없으며 끝난(locked and finished) 상태가 된다.
도커 이미지는 layer로 구성되어 있다
Dockerfile에서 명령어의 순서는 중요하다("The order of Dockerfile instructions matters").
각 명령어는 한 layer에 대강 대응한다고 보면 된다. (공식 문서도 꼼꼼히 읽어볼 것: https://docs.docker.com/build/guide/layers/)
image에 수정이 가해졌다고 다시 처음부터 쌩으로 build하는 건 중복이 많고 비효율적인 작업이다.
수정을 하지 않은 똑같은 부분은 그대로 저장(=cache)해두었다가 활용하고, 바뀐 부분만 업데이트해서 빌드하면 더 빠를 것이다.
그렇기 때문에 Dockerfile에서 image를 빌드하는 과정은 분명히 순서가 존재(=layer 구조)한다.


어떤 코드를 수정했다고 하자.
수정한 layer 다음의 모든 layer는 사실 그대로인데, 이 layer들을 처음부터 다시 rebuild하는 건 비효율적인 것 같다.
이 문제를 어떻게 해결할 수 있을까?
다시 node image의 Dockerfile로 돌아가보자.
비효율적인 방식 (Dockerfile로 image build하기)
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
코드 일부를 수정하면 COPY 명령어의 layer부터 다시 build해야 한다.
그러면 코드만 바뀌었을 뿐 사실 node 패키지는 다시 새로 설치(npm install
)할 필요가 없는데,
RUN 명령어는 COPY 이후의 layer에 해당하니 npm을 새로 설치하게 된다. 분명 불필요한 작업이다.
이 부분을 어떻게 optimization해야 할까?
개선된 방식 (Dockerfile로 image build하기)
Dockerfile에서 명령어 순서를 좀 바꿔주었다.
우선 package.json 파일을 복사해서 npm을 설치하는 데 꼭 필요한 의존성 패키지를 준비해놓고,
그 다음에 npm을 설치한 다음
로컬에 있는 모든 파일을 컨테이너에 복사한다.
FROM node
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
이렇게 하면
1) RUN 명령어는 COPY 명령어 이전에 있기 때문에,
COPY 명령어(COPY . /app)의 layer에서 수정이 되어 cache가 invalidate되어도
이미 RUN npm install 파트는 지나왔다(cache를 활용).
즉 불필요하게 npm을 다시 설치하지 않는다.
2) 이 Dockerfile에 대한 캐시가 없더라도
COPY package.json /app 에서 npm을 설치하기 위한 패키지를 package.json으로 가져오기 때문에
아무런 문제 없이 npm install을 실행할 수 있다.
'도커와 쿠버네티스' 카테고리의 다른 글
[2주차] Part 4: 도커 이미지 공유하기(push, pull) (0) | 2024.01.09 |
---|---|
[2주차] Part 3: 도커 이미지와 컨테이너를 관리하기 (1) | 2024.01.09 |
[2주차] Part 1: 이미지(image)와 컨테이너(container) 간의 관계 (0) | 2024.01.09 |
[1주차] Part 2: 도커 실습 시작하기 (1) | 2024.01.02 |
[1주차] Part 1: 우리가 도커(Docker)를 써야 하는 이유 (1) | 2024.01.02 |