오늘은 Docker를 이용해 MongoDB와 Node.js를 연동하는 것을 공부해보고자한다.
MongoDB를 구동시키는 Container와 Node.js를 구동시키는 Container를 생성하고 둘을 하나의 도커네트워크에서 구동하도록 만든 후 잘 작동하는지 간단히 테스트해본다.
Docker 환경을 구성하는 방법에는 여러가지가 있다. 그 중 우리는 컨테이너 구성을 문서화한 Dockerfile 및 docker-compose 방식을 사용할 것이다. 이 두 방식의 장점은 컨테이너의 환경을 한 눈에 알 수 있기 때문에 유지보수적인 면에서 관리하기 굉장히 용이하다.
# ./Dockerfile
FROM ubuntu:18.04
RUN apt update
RUN apt install wget -y
RUN apt install curl -y
RUN cd ~
RUN curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
RUN bash nodesource_setup.sh
RUN apt install nodejs -y
RUN apt-get install build-essential -y
RUN npm install express -g
RUN npm install express-generator -g
RUN npm install pm2 -g
RUN express /root/expressapp
WORKDIR /root/expressapp/
# npm i는 npm install과 같음
RUN npm i
# mongoose 설치
RUN npm i mongoose
RUN npm audit fix
# ./docker-compose.yml
version: "3.8"
services:
node:
build:
context: .
dockerfile: ./Dockerfile
ports:
- "8000:3000"
container_name: node
command:
pm2-runtime start bin/www --watch --name main
mongo:
image: mongo:4.4.1-bionic
container_name: mongo
Dockerfile과 docker-compose.yml을 작성 후 리눅스 쉘에 다음과 같이 입력하면,
$ docker-compose up -d
위처럼 잘 생성되었다고 출력된 경우 성공.
도커 컨테이너도 잘 작동하고 있다.
두 컨테이너의 docker network ip 정보를 알아내기 위해 다음의 명령어를 이용하여 어떤 docker network에 연결되었는지를 알아낸다.
$ docker network ls
본인의 경우 express-tutorials_default 라는 docker network에 묶여있었다. 따로 설정하지 않을 경우 {프로젝트 폴더명_default}으로 설정되는 듯 하다.
$ docker inspect {docker_network_name}
위의 명령어를 통해 해당 network에 묶인 컨테이너 중 mongo의 ip주소를 알아낸다.
프로젝트 폴더의 app.js 파일 중간에 mongoose 모듈을 추가하고 알아낸 ip주소를 통해 db와 연결한다.
// ./expressapp/app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
// --------------------------------------------------------------------------------
const mongoose = require('mongoose');
// --------------------------------------------------------------------------------
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// --------------------------------------------------------------------------------
mongoose.connect('mongodb://172.18.0.3', { useNewUrlParser: true });
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log('We are connected!');
});
// --------------------------------------------------------------------------------
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
그리고
$ pm2 log
로그를 보면
잘 연결된 것을 확인할 수 있다.
routes폴더 내에 kitten.js 파일을 생성한다.
그리고 app.js 파일에 kitten router를 추가한다.
// ./expressapp.app.js
// ................
// ................
// ................
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var kittenRouter = require('./routes/kitten');
// ................
// ................
// ................
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/kitten', kittenRouter);
// ................
// ................
// ................
models 폴더를 생성하고 내부에 kitten.js 파일을 생성해준다. 자주 사용하게 되는 코드라 따로 이렇게 파일로 빼서 정리해주는 것이 좋다.
각 파일의 내용은 다음과 같이 작성한다.
// models/kitten.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
const kittySchema = new mongoose.Schema({ name: String });
const kitten = mongoose.model('kitten', kittySchema);
module.exports = kitten;
// routes/kitten.js
var express = require('express');
var router = express.Router();
var kitten = require('../models/kitten');
var kittenModel = new kitten();
router.post('/', function (req, res, next) {
var { name } = req.body;
console.log(req.body);
kittenModel.name = name;
kittenModel
.save()
.then(newKitten => {
console.log('Save [' + name + ']');
res.status(200).json({
message: 'Success',
data: {
kitten: newKitten
}
});
})
.catch(err => {
res.status(500).json({
message: err
});
});
});
router.get('/', function (req, res, next) {
kitten
.find()
.then(kittens => {
res.status(200).json({
message: "Success",
data: {
kitten: kittens
}
});
}).catch(err => {
res.status(500).json({
message: err
});
});
});
module.exports = router;
기본 mongodb는 다음과 같이 구성되어있다.
여기에 Postman 등으로 빨간 박스 부분처럼 입력 후 Send 버튼을 누르게되면 성공했다는 메세지와 함께 추가한 데이터 내용이 전송된다.
db에도 데이터가 잘 추가된 것을 볼 수 있다.
GET 메소드를 날려 확인해보면 추가했던 데이터가 잘 출력된다.
요즈음 새로운 기술들을 많이 공부하면서 접목시키는 재미가 쏠쏠하다. 어제보다 성장했다. 내일도 성장하자.