이미지를 빌드하면 명령이 실행되어 컨테이너가 작동하며 이미지가 닫힌다
(그렇기 때문에 코드가 변경되어 새 코드를 새 이미지에 복사하려는 경우 처럼 무엇인가를 업데이트 해야 하는 경우 새로 빌드해야한다)
1. 이미지는 레이어 기반임
즉 이미지를 빌드하거나 재빌드할때 변경된 부분이 명령과 그 이후의 모든 명령이 재평가 된다는 의미이다.
같은 이미지를 내부 수정후 재 빌드할경우 굉장히 빨리 완료되는 것을 볼 수 있다
(using cache)라는 메시지도 볼 수 있음
도커는 모든 명령 결과를 캐시하고 이미지를 다시 빌드할 때 명령을 다시 실행할 필요가 없으면 이러한 캐시된 결과를 사용한다
이를 레이어기반 아키텍쳐라고 한다.
2. 이미지는 읽기 전용이다.
즉 명령이 실행되고 이미지가 빌드되면 새로 빌드하지 않는 한 그 코드를 변경할 수 없다. 모든 명령어를 기반으로 하는 이미지 레이어는 레이어를 생성하고, 이러한 레이어는 캐시됩니다.
그런 다음 이미지를 기반으로 컨테이너를 실행하면 그 컨테이너는 기본적으로 Dockerfile에 지정한 명령을 실행한 결과로 코드를 실행 중인 애플리케이션인 이미지 위에 새로운 추가 레이어를 추가합니다.
이렇게 하면 이미지를 레이어로 실행할 때만 활성화되는 최종 레이어가 추가됩니다.
최종 명령 이전의 모든 명령은 이미 이미지의 일부이지만 별도의 레이어입니다.
그리고 아무것도 변경되지 않으면 이러한 모든 레이어를 캐시에서 사용할 수 있습니다.
코드에서 무언가를 변경하면 즉, 여기에 느낌표나 다른 것을 추가하면 무엇을 변경하든 상관없이 docker build .을 반복하여 다시 빌드하면 이제 시간이 더 오래 걸린다는 것을 알 수 있습니다. 캐시의 일부 결과만을 사용하기 때문이죠.
캐시의 작업 디렉토리 명령 결과를 사용했지만 복사 명령의 경우 다시 실행해야 함을 알아챈 거죠.도커가 복사해야 할 파일을 스캔하고 하나의 파일이 변경된 것을 감지하여 모든 파일을 다시 복사하기 때문입니다.
자, 여기에 중요한 것이 있습니다.
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
하나의 레이어가 변경될 때마다 다른 모든 레이어가 다시 빌드된다고 말했습니다. (역자주: 레이어 변경 후의 모든 레이어) 도커는 npm install이 이제 이전과 동일한 결과를 산출할지 그 여부를 알 수 없습니다.
결국 우리는 파일을 다시 복사하고 도커는 npm install에 영향을 줄 수 있는 위치와
변경한 파일에 대한 심층 분석을 수행하지 않습니다.
즉, 한 레이어가 변경될 때마다모든 후속 레이어도 다시 실행되므로 여기에서 npm install이 다시 실행됩니다.
도커는 다시 실행해야 하는 항목만 다시 빌드하여 다시 실행하여, 이미지 생성 속도를 높이기 위해 존재합니다. 물론 이것은 매우 유용한 메커니즘입니다. 그것은 또한 현재 우리가 코드에서 무엇인가를 변경할 때마다npm install을 다시 실행한다는 것을 의미합니다.
비록 우리가 개발자로서 이것이 불필요하다고 언급했음에도 불구하고 말입니다.프로젝트의 종속성을 관리하는 package.json에서 무언가를 변경하지 않는 한 npm install을 다시 실행할 필요가 없죠.
소스 코드에서 무언가를 변경한 경우 이 프로젝트에 필요한 종속성에 영향을 미치지 않으므로 노드 세계에서 npm install을 다시 실행할 필요가 없습니다.
그리고 여기 이 Dockerfile에 대한 최적화 가능성의 첫 번째 부분이 있습니다.
이렇게 모두 복사한 다음 npm install을 실행하는 대신 npm install 후에 모두를 복사하고, npm install을 실행하기 전에 package.json 파일도 /app에 복사하는 겁니다.
FROM node
WORKDIR /app
COPY package.json /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
이를 통해 이 package.json 파일을 선택하여 app 폴더에 복사한 다음 npm install을 실행하고 다른 코드를 복사합니다.
이로써, 우리의 소스 코드를 복사하기 전에 npm install 레이어가 오게 되는 거죠.따라서 앞으로는 소스 코드를 변경할 때마다 소스 코드 복사 명령 앞의 이러한 레이어가 무효화되지 않습니다.
npm install은 다시 실행되지 않습니다.
우리의 소스 코드를 다시 복사하더라도 말이죠.따라서 이제 이들 레이어만 다시 실행되며 완료하는데 어느 정도 시간이 걸리는 npm install을 다시 실행하는 것보다 성능이 더 좋을 겁니다.
이제 이것을 다시 빌드하면 처음으로 npm install을 실행하고 모든 것을 복사하고, 여기에 이미지 이름이 있습니다.
이제 이를 사용하여 컨테이너를 실행하고 다시 로드하면 이전에 변경한 소스 코드의 변경사항을 볼 수 있습니다. 이제 docker stop으로 이 컨테이너를 중지하고, server.js로 이동하여 소스 코드를 다시 업데이트하여 모든 느낌표를 다시 제거해보죠.
docker build .으로 이미지를 다시 빌드하면다시 매우 빨라진 걸 알 수 있죠. npm install의 캐시된 결과를 사용할 수 있기 때문입니다.
도커가 package.json 파일이변경되지 않았음을 확인했기 때문에 즉, npm install 이전 단계가 변경되지 않았기 때문에 이전과 동일하므로 다시 복사하고 npm install을 다시 실행할 필요가 없게 된 거죠.
이 단계에서 유일한 변경 사항이 발생했지만 이는 npm install 이후에 발생합니다.