리셋 되지 말자

[CSAPI] nodejs, mongodb 컨테이너 추가 본문

프로젝트

[CSAPI] nodejs, mongodb 컨테이너 추가

kyeongjun-dev 2021. 9. 22. 14:57

추가되는 NodeJS, MongoDB 컨테이너

사용자와 직접 상호작용(?)하는 NodeJS 서비스 컨테이너를 추가한다. 이 서비스는 주로 사용자의 회원가입, 로그인, 로그아웃 등의 작업을 처리하는데 사용자 정보를 저장할 DB도 필요하다. 여기서는 MongoDB를 사용하도록 한다.

- 예상 구성

Node 컨테이너 추가

사용자가 실제 서비스를 이용할 때는 Nginx를 통해 node에 접속하게 된다. 이때 proxy를 이용해 접속하도록 한다. 이를 위해 node 컨테이너는 3000번 port를 expose 하게 된다.

우선, 간단히 hello world를 출력하는 node의 코드를 추가하여 nginx proxy로 node 서비스가 가능한지 확인해본다.

1. node 디렉토리 생성 및 필요한 파일 작성

node 디렉토리를 새롭게 만들고, 아래의 파일들을 node 디렉토리 아래에 작성한다.

- node 디렉토리가 추가된 디렉토리 구조

.
├── docker-compose.yml
├── nginx
│   ├── certificate.crt
│   ├── default.conf
│   ├── Dockerfile
│   └── private.key
├── node
│   ├── Dockerfile
│   ├── index.js
│   └── package.json
└── README.md

 

- index.js

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

 

- package.json

{
  "name": "csapi-node",
  "version": "1.0.0",
  "description": "csapi user auto service",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Penguin135",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}

 

- Dockerfile

FROM node:14.17.0
WORKDIR /node
COPY . .
RUN npm install

 

2. nginx proxy 설정

node 컨테이너로 proxy를 하도록 nginx 설정을 한다. 현재는 node 서버가 하나밖에 없어서 Load Balancing 방식이 필요할까 싶지만 우선은 ip_hash 방식으로 해두었다. Round Robin, Random, Weighted 등 많은 방식이 있다.

- default.conf

upstream node {
  ip_hash;
  server node:3000;
}

server {
    listen      80;
    server_name test.csapi.kro.kr;
    return      301 https://$server_name$request_uri;
}

server {
    listen       443 ssl;

    ssl on;
    ssl_certificate /etc/ssl/certificate.crt;
    ssl_certificate_key /etc/ssl/private.key;
    server_name  test.csapi.kro.kr;

    location / {
      proxy_pass http://node/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

 

3. docker-compose.yml 에 node 서비스 추가

- docker-compose.yml

version: "3"
services:
  nginx:
    build: ./nginx
    image: csapi-nginx:test
    ports:
      - "80:80"
      - "443:443"

  node:
    build: ./node
    image: csapi-node:test
    expose:
      - "3000"
    commnad: "node index.js"

 

4. code push

gitlab-runner 가 파이프라인을 수행했고, passed 가 됐다.

 

5. 도메인 접속 테스트

접속 시, node 컨테이너 서비스 사용이 가능하다.

 

 

MongoDB 컨테이너 추가

사용자 정보를 저장할 mongodb 컨테이너를 추가한다. mongodb 컨테이너는 nodejs 에 연결되고, 이를 위해 mongoose패키지를 추가로 사용한다.

1. node 의 index.js, package.json 파일 수정

index.js 에서는 mongodb에 연결하고, 연결에 성공하면 성공 했다는 log 를 출력하도록 한다. 그리고 nodejs에서 mongodb에 연결하기 위한 패키지인 mongoose를 설치하도록 package.json에 추가해준다.

- package.json

{
  "name": "csapi-node",
  "version": "1.0.0",
  "description": "csapi user auto service",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Penguin135",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "mongoose": "^6.0.7"
  }
}

 

- index.js

const express = require('express')
const mongoose = require('mongoose')

const app = express()
const port = 3000

mongoose.connect('mongodb://mongo:27017', {
  useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false
}).then(() => console.log('MongoDB Connected...'))
  .catch(err => console.log(err))



app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

 

2. docker-compose.yml 에 mongo 서비스 추가

mongodb 컨테이너를 추가한다. 사용하는 이미지 태그가 latest 인데, latest를 사용하는 것은 원래는 추천되지 않는다. 명심하자.

- docker-compose.yml

version: "3"
services:
  nginx:
    build: ./nginx
    image: csapi-nginx:test
    ports:
      - "80:80"
      - "443:443"

  node:
    build: ./node
    image: csapi-node:test
    expose:
      - "3000"
    command: "node index.js"

  mongo:
    image: mongo:latest
    expose:
      - "27017"

 

3. mongoose 관련 이슈 핸들링

이전 mongoose를 이용해 사용자 관리를 구현했을 때는 버젼이 5.2였는데, 6.0 이상 부터는 true, true, true, false를 default로 실행한다고 한다. (링크)
따라서 해당 옵션들을 제거하고 다시 index.js를 작성했다.

- index.js

const express = require('express')
const mongoose = require('mongoose')

const app = express()
const port = 3000

mongoose.connect('mongodb://mongo:27017', {
}).then(() => console.log('MongoDB Connected...'))
  .catch(err => console.log(err))



app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

 

4. 수정된 코드 push

gitlab-runner 가 pipeline을 수행하도록 했다. 업데이트가 되었지만, 도메인에 접속하여 달라지는 결과는 없다.

 

실제 서버에 접속하여 확인해 보면, 정상적으로 3 개의 컨테이너 구동 중임을 확인할 수 있다.

 

log 도 정상적으로 출력되었다.

 

후기

mongodb 컨테이너를 추가했지만, 잘 추가되었는지 확인할 방법이 log 한 줄 뿐이다. 이전에 nodejs 컨테이너와 mongodb 컨테이너를 연결시키기 위해서는 mongodb가 연결 준비가 된 상태까지 기다릴 필요가 있어서 wait-for-ti.sh(링크) 스크립트 파일을 이용했었는데 현재는 별도의 스크립트를 사용하지 않아도 연결이 잘 된다. 지금은 잘 되지만 나중에 안될 수도 있으니 명심해 두자.

위에서도 언급했지만, 현재 mongodb 컨테이너가 추가되었음에도 잘 연결이 되는지 확인할 수 있는 방법이 직접 서버에 들어가서 log 를 확인하는 방법밖에 없다. test 단계에서 간단히 데이터를 하나 mongoose를 통해 추가하고, 추가가 되었는지 확인하는 코드를 추가하는 방법으로, 정상적으로 mongodb 컨테이너가 연결되어 동작하는지를 테스트할 수 있어야 할 것 같다.

Comments