도커 이미지는 코드의 변경 사항이 있을 때 마다 새로 만들어야합니다
여기서 레이어라는 개념이 등장합니다.
이미지를 빌드하거나 이미지를 다시 빌드할 때
변경된 부분의 명령과 그 이후의 모든 명령이 다시 빌드 된다는 의미입니다.
Using cache(캐쉬 사용)이라는 메시지를 볼 수 있습니다.
도커는 기본적으로 이 모든 명령어에 대해 다시 실행했을 때의 결과가 이전과 동일하다는 것을 인식했기 때문입니다.
동일한 작업 디렉토리를 가지고 있고 복사한 코드는 전혀 변경되지 않았으며 새 파일도 없고 변경된 파일도 없으므로 도커는 실제로 그 명령을 다시 거칠 필요가 없다고 추론합니다.
대신 이미지를 빌드할 때마다 도커는 모든 명령 결과를 캐시하고 이미지를 다시 빌드할 때 명령을 다시 실행할 필요가 없으면 캐시된 결과를 사용합니다.
이것을 레이어 기반 아키텍처라고 합니다.
모든 명령은 Dockerfile의 레이어을 나타냅니다. 그리고 이미지는 이러한 다양한 명령을 기반으로
여러 레이어에서 간단하게 구성됩니다. 또한 이미지는 읽기 전용입니다.
즉, 일단 명령이 실행되고 이미지가 빌드되면 이미지가 잠기고,
이미지를 다시 빌드하지 않는 한 그 코드를 변경할 수 없습니다.
이는 기술적으로 새 이미지를 생성한다는 의미입니다.
모든 명령어를 기반으로 하는 이미지 레이어는 레이어를 생성하고, 이러한 레이어는 캐시됩니다.
그런 다음 이미지를 기반으로 컨테이너를 실행하면 그 컨테이너는 기본적으로 Dockerfile에 지정한 명령을 실행한 결과로 코드를 실행 중인 애플리케이션인 이미지 위에 새로운 레이어를 추가합니다.
그래서 레이어를 알아서 얻는게 뭔데?
기존 이미지에 추가적인 변경이 있을 때, 모두 다시 받는 것이 아닌 해당 파일만 교체 및 추가하기 위해 사용합니다.
그러면 예제를 같이 보겠습니다. 이전에 Dockerfile은 다음과 같습니다.
# node가 설치된 docker 이미지를 가져온다.
From node
# /app 폴더 내부에서 실행될 것임을 설정한다.
WORKDIR /app
# 현재 Dockerfile 경로에 있는 파일들 전부를 도커 이미지 내부 /app 경로에 복사한다.
COPY . /app
# package.json 파일을 설치
RUN npm install
# 만약 node 앱에 80포트로 서버를 열어놨다면 container의 외부 포트를 설정해주어야한다.
EXPOSE 80
# 마지막 server.js 파일을 실행한다.
RUN node server.js
# CMD의 경우 이미지 기반으로 컨테이너가 실행 될 때 실행됩니다.
# CMD ["node", "server.js"]
위의 코드의 경우 처음부터 COPY를 통해 파일 전체를 가져옵니다.
이럴 경우 파일이 하나라도 바뀌면 Docker는 npm install 의 결과를 알 수 없습니다.
그렇기에 npm install을 다시 하게됩니다. 물론 시간도 더 걸립니다.
그러면 최적화된 다음 코드를 보겠습니다.
# node가 설치된 docker 이미지를 가져온다.
From node
# /app 폴더 내부에서 실행될 것임을 설정한다.
WORKDIR /app
# 현재 package.json 파일만 /app 경로에 복사한다.
COPY package.json /app
# package.json 파일을 설치
RUN npm install
# 현재 Dockerfile 경로에 있는 파일들 전부를 도커 이미지 내부 /app 경로에 복사한다.
COPY . /app
# 만약 node 앱에 80포트로 서버를 열어놨다면 container의 외부 포트를 설정해주어야한다.
EXPOSE 80
# 마지막 server.js 파일을 실행한다.
RUN node server.js
# CMD의 경우 이미지 기반으로 컨테이너가 실행 될 때 실행됩니다.
# CMD ["node", "server.js"]
먼저 package.json 파일만 먼저 복사한 후 npm install로 라이브러리들을 설치했습니다.
그 후에 실행 파일들을 /app 경로로 복사했습니다.
이 경우 package.json이 바뀌지 않았다면 layer 일부분을 재사용 할 수 있게됩니다.
'도커' 카테고리의 다른 글
docker 기본 명령어 (0) | 2022.06.19 |
---|---|
Docker - volume (0) | 2022.06.19 |
Docker - Dockerfile (0) | 2022.06.19 |
Docker - Container, Image (0) | 2022.06.19 |
Docker 설치 (window, linux) (0) | 2022.06.19 |
댓글