ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [따라하며 배우는 도커와 CI환경] 4. 도커를 이용한 간단한 Node.js 어플 만들기
    DevOps/Docker 2022. 5. 22. 15:33

    이제부터 매우 간단한 Nodejs 앱을 도커 환경에서 실행해보자.

     

    ✔️ 아주 간단한 Node.js 앱 만들기

    도커 실습을 위한 것이기 때문에 앱은 최대한 간단하게 만들어보자!
    Nodejs 프로젝트를 생성해주고 다음과 같이 파일을 추가한다.

    package.json

    {
      "name": "nodejs-docker-app",
      "version": "1.0.0",
      "description": "",
      "main": "server.js",
      "scripts": {
        "start": "node server.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "express": "^4.18.1"
      }
    }

     

    server.js

    const express = require('express');
    
    const PORT = 8080;
    
    const app = express();
    app.get('/', (req, res) => {
        res.send('Hello World');
    });
    
    app.listen(PORT);
    console.log("Server is running");

     

     

    ✔️ Dockerfile 작성

    Nodejs 앱을 도커 환경에서 실행하려면 먼저 이미지를 생성해야 한다.

    지금부터 이미지를 생성하기 위한 설정 파일인 Dockerfile을 작성해보자.

    FROM node:14
    
    COPY ./ ./
    
    RUN npm install
    
    CMD ["node", "server.js"]

    📍FROM node:14   
    node 14 버전을 베이스 이미지로 한다.

    📍 COPY ./ ./   
    프로젝트 내의 ./ 경로에 있는 모든 파일 (package.json, server.js 등)을 도커 컨테이너의 ./로 넣어준다.
    *앞부분은 로컬 프로젝트 경로, 뒷부분은 컨테이너의 경로이다.

    만약 이 부분이 없다면❓

    위와 같이 파일을 찾을 수 없다는 오류가 발생한다.
    따라서, 컨테이너에 로컬 파일들을 넣어주기 위해서 COPY 명령어를 추가해야 한다! 

    📍 RUN npm install   
    npm install 을 통해
    dependency(ex. express) 를 설치한다.

    📍 CMD ["node", "server.js"]
    node server.js 명령어를 통해 노드 앱을 실행한다.

     

     

    ✔️ 빌드 및 실행

    $ docker build -t [이미지 이름] ./
    $ docker run -p [컨테이너 외부 포트 번호]:[컨테이너 내부 포트 번호] [이미지 이름]

    위의 명령어를 통해 이미지를 빌드하고, 그 이미지를 통해 컨테이너를 실행할 수 있다.

    여기서 중요한 것은 -p 옵션을 통해 포트 매핑을 해주어야 한다는 점이다.
    이 부분이 없다면, 컨테이너 내부에서 동작하는 서버로 접속할 수 없다❗️

    다음과 같이 포트 매핑 없이 실행하면 서버에 접속할 수 없다.

     

    포트 매핑을 설정해주면 아래와 같이 8080 포트로 접속할 수 있다.

     

    ✔️ Working Directory 지정하기

    WORKDIR [경로]

    Dockerfile에 WORKDIR 이라는 키워드를 통해 애플리케이션 소스 코드를 저장할 디렉터리를 생성할 수 있다.

    working directory를 지정하지 않으면 소스 파일들이 '/ ' 경로에 들어가게 된다. 
    이때 원래 베이스 이미지에 있던 파일과 이름이 같을 경우, 덮어쓰게 되어  베이스 이미지의 파일을 읽게 되어 문제가 될 수 있다.
    따라서 애플리케이션을 위한 모든 소스 파일들은 working directory에 따로 보관하는 것이 좋다.

    Dockerfile을 다음과 같이 수정해주자.

    FROM node:14
    
    WORKDIR /usr/src/app
    
    COPY ./ ./
    
    RUN npm install
    
    CMD ["node", "server.js"]

     

     

    ✔️ 재빌드 효율적으로 하기

    재빌드를 효율적으로 하기 위해 Dockerfile을 다음과 같이 수정해주자.

    FROM node:14
    
    WORKDIR /usr/src/app
    
    COPY package*.json ./
    
    RUN npm install
    
    COPY ./ ./
    
    CMD ["node", "server.js"]

    npm install 전에 package*.json 파일을 복사해주고, npm install 후에 모든 파일을 복사하도록 변경했다.
    이렇게 하는 이유는 npm install 시, 불필요한 다운로드를 피하기 위해서다.

    이전 같은 경우는, npm install 전에 모든 파일을 복사하였기 때문에, 의존성과 관계없는 수정을 하여도 파일이 달라졌다고 판단하여 npm install을 실행하였다. 그런데 위와 같이 바꿔주면 package.json이 변경된 경우만 npm install을 수행하고 나머지 경우는 cache를 사용하기 때문에 보다 효율적이다.

    📌 비효율적인 재빌드

     => [2/3] COPY ./ ./                                                                                                  

     => [3/3] RUN npm install      
    📌 효율적인 재빌드

     => CACHED [2/4] COPY package*.json ./                                                                                

     => CACHED [3/4] RUN npm install                                                                             
     => CACHED [4/4] COPY ./ ./    

     

     

    ✔️ Docker Volumes

    지금까지 변경된 소스를 컨테이너에 적용하려면, 변경된 소스 파일을 copy한 후에 이미지를 다시 빌드해야 했다.
    이런 과정은 꽤나 번거로운 작업이다.

    docker volume을 사용하면 소스가 변경되어도 다시 빌드하지 않고도 변경된 내용을 컨테이너에 적용할 수 있다.
    docker volume은 도커 컨테이너에서 호스트 디렉터리에 파일을 매핑해서 사용한다.

     

    다음 명령어를 통해 호스트 디렉토리와 컨테이너 디렉토리를 매핑해줄 수 있다.

    $ docker run -v [호스트 디렉토리]:[컨테이너의 디렉토리] [이미지 이름]

     

    node_modules를 제외하고, 호스트 디렉토리와 컨테이너의 working directory를 매핑해준다.
    * $(pwd) 는 현재 디렉토리 위치를 의미한다.

    $ docker run -d -p 8080:8080 -v /usr/src/app/node_modules  -v $(pwd):/usr/src/app [이미지 이름]

     

    이제 server.js를 수정하고 컨테이너를 stop 후 다시 run 하면 변경된 내용이 적용된 것을 확인할 수 있다.

     

     

    참고

     

     

    728x90

    댓글

Designed by Tistory.