Build Docker image NodeJS App (Express) using Dockerfile, .dockerignore, Layer Caching

 이번 글에서는 Dockerfile 과 .dockerignore 파일을 이용하여 express 프레임워크를 사용한 node JS application 을 build 하고 Dockerfile 작성 시 Image layer 캐싱에 대하여 간단하게 정리해보겠다.

우선, 정말로 간단한 express application 이다. 

https://expressjs.com/ko/starter/installing.html

user-service-api 라는 directory 를 생성하고, npm 을 통해 express 를 사용할 수 있도록 하였다.



index.js 를 아래와 같이 작성했다. 3000 port 로 서빙한다. / path 접근 시 정적으로 name, email 을 형식의 object 를 array 로 내려준다.


이제 Dockerfile 을 작성해보자.
node 최신 이미지를 base image 로 사용하고, /app 을 working directory 로 설정한다.
그리고 현재 user-service-api directory 밑에 모든 파일을 /app 밑에 ADD 한다.
그리고 npm 명령어를 통해서 의존성을 설치하고, CMD 를 통해 container 가 run 할 때 index.js 를 실행한다.



docker -t user-service-api:latest . 를 통해서 build 한다.

npm install 명령어를 하게 되면 package.json 의 dependencies 를 node_modules 밑에 설치하게 된다.
설치된 의존성에 대한 snapshot 이 package-lock.json 파일에 남는다.

따라서 image 를 빌드할 시점에 node_modules 밑에 있는 의존성은 추가될 필요가 없다.
그래서 .dockerignore 파일을 작성하여 제외시키도록 하자.
또한 Dockerfile 및 .git 아래에 있는 해당 레포지토리에 대한 정보들 또한 build 에 필요없는 정보라서 같이 제외시킨다.

이외에도 build 에 필요하지 않는 파일들을 .dockerignore 파일에 작성하여 제외시킬 수 있다.


다시 동일하게 docker -t user-service-api:latest . 를 통해서 build 한다.




Docker 는 container image 를 생성할 때 layer 를 사용한다. Dockerfile 안에 작성된 각각의 command 는 새로운 layer 를 생성한다. 각 layer 는 image 의 command 가 실행되기 전의 상태와 command 가 실행되고 나서의 파일시스템의 변화를 포함한다.

Docker 는 이 과정에서 layer cache 를 통해서 image 를 build 할 때 보다 빠르게 build 할 수 있도록 최적화한다.

Docker layer caching 은 주로 RUN, COPY, ADD command 에서 작동한다. 따라서 Dockerfile 을 작성할 때 COPY, ADD , RUN 이 3가지 command 를 어떻게 작성하느냐에 따라서 이미지를 보다 빠르게 build 할 수 있는지가 갈린다.

위에서 먼저 작성한 Dockerfile 로 build 할 때 
---> Using cache 라는 출력을 확인할 수 있는데, 해당 부분들이 layer caching 을 사용하고 있는 부분이다.

이번에는 Docker 가 layer caching 을 사용할 수 있도록 Dockerfile 을 변경해보겠다.
먼저 작성한 Dockerfile 에서는 ADD . . command 가 npm install command 보다 먼저있었다.
아래에서 변경된 사항은 
ADD package*.json ./ command 를 먼저하고 후에
RUN npm install command 를 실행하여 의존성을 설치할 때 보다 빠르게 캐싱을 적용하였다.

위에서 언급했지만, package.json 을 통해서 의존성을 node_moules 밑에 설치하고, package-lock.json 의 의존성들의 버전관리가 snapshot 이 이루어진다. 

또한 application 개발 시 의존성의 변화는 source code 의 변화보다 매우 적기때문에 cache 의 적용대상이 되는것이 맞다.

따라서, 먼저 ADD package*.json 을 working directory 에 추가하고, 
RUN npm install command 를 통해 의존성을 설치하고,
.dockerignore 에서 제외된 모든 source code 를 working directory 에 추가하는
ADD . .  command 를 실행한다.


변경된 Dockerfile 을 통해서 build 하기, 변경된 Dockerfile 의 경우 새로운 command 가 추가되고 처음 build 하기 때문에 layer cache 가 불가능하다. 따라서 한 번더 build 하여 log 를 통해서 확인해보자.


3/6 : ADD package*.json ./
4/6 : RUN npm install 
두 개의 명령어 밑에  ---> Using cache log 를 확인할 수 있다. 이를 통해 layer cache 가 적용되었고, 보다 빠르게 image build 가 가능하다.


마지막으로 run 

브라우저에서 해당 container 가 잘 서빙하고 있는것을 확인한다.



이번 글은 여기서 마무리하도록 하겠다 : )

해당 repository 에서 확인이 가능하다.


댓글

이 블로그의 인기 게시물

About Kafka Basic

About JVM Warm up

About ZGC

Spring Boot Actuator readiness, liveness probes on k8s

About G1 GC

sneak peek jitpack

About idempotent

C 언어 구조체의 포인터 멤버 변수

Synology NAS에 MariaDB 10에 Mysql workbench로 원격접속하기

About Websocket minimize data size and data transfer cost on cloud