본문 바로가기

Programming/Docker

Node.js 웹 앱의 도커라이징

해당 글은 node.js의 공식 문서인 Dockerizing a Node.js web app을 참고하여 작성했다.

잘 작동하는 Node.js 애플리케이션을 docker container에서 실행시키는 방법에 대한 글이다. production 배포용이 아닌 개발용의 내용만 다루고 있다. (후에 작성해볼 예정이다.) 도커에 대한 기본적인 이해와, Node.js 애플리케이션의 기본 구조에 대한 이해가 있는 사람들에게 추천하는 글이다.

0. Dockerizing?

도커라이징이란 해당 애플리케이션을 도커 컨테이너에서 실행할 수 있도록 하는 과정이다.

 

0.1. How to Dockerize?

도커 컨테이너에서 내가 만든 애플리케이션이 실행되도록 하려면 어떻게 해야 할까? 바로 docker image를 만들면 된다.

1. Dockerfile 작성하기

현재 내 어플리케이션의 package.json은 다음과 같다. 각자 scripts를 확인하면서 해당 글을 따라 하면 좋을 것 같다.

// package.json
{
  "name": "backend",
  "version": "1.0.0",
  "description": "Node.js + Docker",
  "main": "server.js",
  "scripts": {
    "build": "tsc",						// compile type
    "start": "env NODE_ENV=prod node build/app",		// run with prod env
    "start:dev": "env NODE_ENV=dev nodemon",			// run with dev env
    "test": "env NODE_ENV=test mocha --exit --timeout 10000"	// test with mocha
  },
  "dependencies": {
  	...
  }
}

 

docker image를 만들어보자. 미리 완성된 express app에 Dockerfile을 생성해보자.

$ touch Dockerfile

 

생성된 Dockerfile에 차근차근 작성 해나 가보자.

가장 먼저 해야 할 일은, 어떤 image를 사용하여 build 할 것인지 정의하는 것이다. Docker Hub에 있는 공식적인 node image를 가져와서 사용할 것이다. 각자 원하는 node 버전을 입력해주면 된다. 이 글에서는 12.14.1 버전을 사용하였다.

 

#FROM node:<version>
FROM node:12.14.1

 

Docker Hub node 공식 이미지 해당 페이지에서 지원하는 버전들을 확인할 수 있다.

 

node - Docker Hub

Supported tags and respective Dockerfile links 8.16.2-jessie, 8.16-jessie, 8-jessie, carbon-jessie 8.16.2-jessie-slim, 8.16-jessie-slim, 8-jessie-slim, carbon-jessie-slim 8.16.2-stretch, 8.16-stretch, 8-stretch, carbon-stretch, 8.16.2, 8.16, 8, carbon 8.16

hub.docker.com

이미지 안에 애플리케이션 코드를 넣기 위해 폴더를 생성해보자. app 폴더는 해당 애플리케이션의 working directory가 될 것이다.

# create app directory
RUN mkdir -p /app
WORKDIR /app

 

해당 이미지에는 이미 Node.js와 NPM이 설치되어있으므로 npm binary를 사용해 app dependency들만 설치해주면 된다.

# Install App dependencies
COPY package.json /app
COPY package-lock.json /app
RUN npm install

# A wildcard is also available
COPY package*.json /app

 

package.json과 package-lock.json을 복사한 후, npm install을 통해 node_modules를 설치한다. 참고로 wildcard 옵션도 사용할 수 있다. 여기서 node_modules를 직접 복사하지 않는 이유는, 캐시 전략을 통해 효율적으로 docker layer를 사용할 수 있다는 점이다. 자세한 설명은 이 글에서 확인할 수 있다.

 

애플리케이션의 소스 코드를 도커 이미지에 넣어주자.

# bundle app source
COPY . /app

 

현재 내 어플리케이션의 port 번호는 8080 포트에 바인딩되어 있으므로 docker daemon에 다음과 같이 매핑해주자.

EXPOSE 8080

 

마지막으로, 앱을 실행할 수 있도록 명령어를 정의해주자. 현재 내 어플리케이션의 script 명령어npm run start:dev를 실행시킬 수 있도록 해보자. 각자 package.json에 정의한 script들을 확인해보길 바란다.

CMD ["npm", "run", "start:dev"]

 

생성된 Dockerfile은 다음과 같다.

FROM node:lts-alphine

RUN mkdir -p /app
WORKDIR /app

COPY package.json /app
COPY package-lock.json /app
RUN npm install

COPY . /app

EXPOSE 8080
CMD ["npm", "run", "start:dev"]

 

node_modules와 debug log들은 복사되지 않도록 .dockerignore 파일을 만들어주자. Dockerfile과 같은 경로에 생성해주면 된다.

// .dockerignore
node_modules
npm-debug.log

 

2. Docker image 빌드하기

Dockerfile이 있는 경로로 이동해서, 다음 명령어를 입력해보자. 이때 <본인의 username>에는 docker hub 아이디를 입력해주고,  <원하는 docker image명>에는 만들고자하는 이미지의 이름을 적어주면 된다. <tag 명>은 선택적이며, 작성하지 않을 경우, latest라는 값이 할당된다.

docker build -t <본인의 username>/<원하는 docker image명>:<tag 명> .

 

만약 2개 이상의 Dockerfile을 사용하고있다면, (개발용, 배포용 등등) -f 태그를 활용해 어떤 Dockerfile을 사용해서 이미지를 빌드할 것인지 명시해주어야 한다.

docker build -f <Dockerfile name> -t <본인의 username>/<원하는 docker image명> .

 

-f (--file) 2개 이상의 Dockerfile을 사용하고 있을 때, 특정 Dockerfile을 지정할 때 사용된다.
-t  image tag의 이름을 지정한다.

 

Dockerfile에 작성한 순서대로 image를 빌드하는 것을 볼 수 있다.

위 명령어를 통해 Dockerfile에 작성한 순서대로 이미지를 만들어주는 것을 확인할 수 있다.

docker image ls

 

해당 명령어를 통해 현재 이미지의 목록을 확인할 수 있다. 

 

docker image ls

3. Docker image 실행하기

만든 docker image를 실행해보자.

docker run -p 8080:8080 -d <본인의 username>/<만든 docker iamge name>

 

-p <public port>:<private port> public port '8080' (컨테이너 내부에서 앱이 실행되는 포트 번호)를 local private포트 '8080'로 리다이렉트 시켜준다
-d  컨테이너를 백그라운드에서 실행시켜준다는 뜻

 

백그라운드에서 실행을 했기 때문에 우리는 해당 이미지가 잘 실행되고 있는지 확인해야 한다. log를 확인해보자.

# Get container ID 
docker ps

# Print logs
docker logs <container ID>

 

 

뿐만 아니라, docker desktop에서도 확인할 수 있다. Docker Desktop 다운로드하기

docker desktop에서도 로그를 확인할 수 있다.

 

반응형

'Programming > Docker' 카테고리의 다른 글

Angular + Nginx 도커라이징  (0) 2020.04.28