[App development 1] [Node.js express Docker] Build an environment for Node.js Express MongoDB (mongoose) using Docker [December 2020]

Application development using Node.js Express MongoDB

We have decided to develop an application using Node.js Express MongoDB as a contract development. I would like to record the knowledge gained during development within a range that does not hinder it. Aside from the contents of the application, since we will develop it as a team, we will first build a development environment using Docker.

Environment to build

--Create an app container and mongodb container using docker-compose. --Save data in the test model using the connection test (mongoose) between the app container and the mongodb container. --Confirm data insertion from mongo compass --Provide authentication for mongodb. The authority of the user to create is "root", "read", "owner" --Database password etc. are managed by environment variables (remove from git management with gitignore)

※important point If it is , please enter an appropriate one. If you write it as it is, an error will occur. This time, all passwords are the same.

List of packages to be initially installed

 "bcrypt"
 "body-parser"
 "connect-flash"
 "cookie-parser"
 "debug"
 "ejs"
 "express"
 "express-ejs-layouts"
 "express-generator"
 "express-session"
 "express-validator"
 "http-errors"
 "http-status-codes"
 "method-override"
 "mongoose"
 "morgan"
 "nodemon"
 "passport"
 "passport-local-mongoose"

Preparation

Files to prepare first

.
├── .env
├── .gitignore
├── data
│   └── db  //Empty directory
├── docker-compose.yml
├── docker_app
│   └── Dockerfile
├── secret_file
│   ├── db.env
│   └── db_init
│         └──mongo_init_user.js
└── src
    ├── controllers
    │     └── initTestsController.js
    ├── models
    │     └── init_test.js
    └── package.json

.env.



MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=<password>
MONGO_INITDB_DATABASE=<DB name>

.gitignore.



node_modules/
data/
.env
secret_file/

docker-compose.yml


version: '3'
services:
  app:
    build: ./docker_app
    container_name: <app name>_app_cnt
    ports:
      - "8080:3000"
    restart: always
    working_dir: /app
    tty: true
    volumes:
      - /etc/passwd:/etc/passwd:ro
      - /etc/group:/etc/group:ro
      - ./src:/app
    env_file:
      - ./secret_file/db.env
    command: bash
    networks:
      - <app name>-network
    depends_on:
      - mongo
  mongo:
    image: mongo:latest
    container_name: <app name>_db_cnt
    ports:
      - "27018:27017"
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
      MONGO_INITDB_DATABASE: ${MONGO_INITDB_DATABASE}
    volumes:
      - ./data/db:/data/db
      - ./secret_file/db_init/:/docker-entrypoint-initdb.d
    env_file:
      - ./secret_file/db.env
    command:
      - mongod
    networks:
      - <app name>-network
networks:
  <app name>-network:
    external: true

Dockerfile.



FROM node:12
WORKDIR /app
RUN npm install

db.env


DB_USER=owner
DB_PASS=<password>
DB_NAME=<app name>_db

mongo_init_user.js


let users = [
  {
    user: "read",
    pwd: "<password>",
    roles: [
      {
        role: "read",
        db: "<app name>_db"
      }
    ]
  },
  {
    user: "owner",
    pwd: "<password>",
    roles: [
      {
        role: "dbOwner",
        db: "<app name>_db"
      }
    ]
  },
  {
    user: "readWriteUser",
    pwd: "<password>",
    roles: [
      {
        role: "readWrite",
        db: "<app name>_db"
      }
    ]
  }
];

for (let i = 0, length = users.length; i < length; ++i) {
  db.createUser(users[i]);
}

initTestsController.js


"use strict";

const InitTest = require('../models/init_test');

const test = () => {
  let initTest = new InitTest({
    name: "Taro",
    age: 20
  })
  initTest.save((error, data) => {
    if (error) {
      console.log(error);
    }
    console.log(data);
  })
}

module.exports = { test };

init.test.js


"use strict";

const mongoose = require("mongoose");

const initTestSchema = new mongoose.Schema({
  name: String,
  age: Number
});

module.exports = mongoose.model("InitTest", initTestSchema);

package.json


{}

Environment creation

Container creation

host.


docker-compose build

The following warning appears, but there is no problem.

npm WARN saveError ENOENT: no such file or directory, open '/app/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/app/package.json'
npm WARN app No description
npm WARN app No repository field.
npm WARN app No README data
npm WARN app No license field.

host.


#Temporarily put the container inside the start container (--Delete after stopping with rm. After starting the container, enter bash)
docker-compose run --rm app /bin/bash

In the app container.


# express-Generate application template with generator
npx express-generator --view=ejs

If it is rejected by aborting immediately for the following, execute again

destination is not empty, continue? [y/N]
aborting

The second time I will wait with a question, so enter with y

destination is not empty, continue? [y/N] y

Various files such as the following are created.

   create : public/
   create : public/javascripts/
   create : public/images/
   create : public/stylesheets/
   create : public/stylesheets/style.css
   create : routes/
   create : routes/index.js
   create : routes/users.js
   create : views/
   create : views/error.ejs
   create : views/index.ejs
   create : app.js
   create : package.json
   create : bin/
   create : bin/www

Overwrite the following contents in package.json

package.json


{
  "name": "uniq_app",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "nodemon ./bin/www"
  },
  "dependencies": {
    "bcrypt": "^5.0.0",
    "body-parser": "^1.19.0",
    "connect-flash": "^0.1.1",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "ejs": "^3.1.5",
    "express": "~4.16.1",
    "express-ejs-layouts": "^2.5.0",
    "express-generator": "^4.16.1",
    "express-session": "^1.17.1",
    "express-validator": "^6.7.0",
    "http-errors": "~1.6.3",
    "http-status-codes": "^2.1.4",
    "method-override": "^3.0.0",
    "mongoose": "^5.11.9",
    "morgan": "~1.9.1",
    "nodemon": "^2.0.6",
    "passport": "^0.4.1",
    "passport-local-mongoose": "^6.0.1"
  }
}

Overwrite the following contents in app.js

app.js


const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const mongoose = require("mongoose");


const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

const initTestController = require('./controllers/initTestsController');

const app = express();

mongoose.connect(
  `mongodb://${process.env.DB_USER}:${process.env.DB_PASS}@mongo:27017/<app name>_db`,
  { userNewParser: true }
);

mongoose.set("useCreateIndex", true);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.get('/initTest', initTestController.test);/*Initial test routing*/
app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Package installation

In the app container.


npm install

Exit the container once

In the app container.


#Exit the container (this temporary container will be deleted)
exit

Restart the container

host.


docker-compose up

Click below to check connection http://localhost:8080/

Check connection with mongoose

Check if the data is created by clicking below http://localhost:8080/initTest

If the following log is output, it is successful (in the terminal where docker-compose up)

uniq_app_cnt |   _id: 5fec5a6213a2fd002d89acca,
uniq_app_cnt |   name: 'initTestUser',
uniq_app_cnt |   age: 20,
uniq_app_cnt |   __v: 0
uniq_app_cnt | }
uniq_app_cnt |【log】--Successful connection--【log】

Check around mongodb permissions

Open the terminal in a separate tab and enter the db container

docker exec -it <app name>_db_cnt bash
mongo
//Connect to mongodb

show dbs
//Nothing is displayed.(Make sure it is locked by authentication)

use admin
//Connect to admin database

db.auth("root", "<password>")

//If 1 is returned, authentication is successful

db.system.users.find().pretty()
//User confirmation created

It's okay if each authorized person for the database is created as shown below.

{
	"_id" : "admin.root",
	"roles" : [
		{
			"role" : "root",
			"db" : "admin"
		}
	]
}
{
	"_id" : "uniq_db.read",
	"roles" : [
		{
			"role" : "read",
			"db" : "<Database name>_db"
		}
	]
}
{
	"_id" : "uniq_db.owner",
	"roles" : [
		{
			"role" : "dbOwner",
			"db" : "<Database name>_db"
		}
	]
}
{
	"_id" : "uniq_db.readWriteUser",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "<Database name>_db"
		}
	]
}

Confirmation of connection from mongo compass.

image.png

Recommended Posts

[App development 1] [Node.js express Docker] Build an environment for Node.js Express MongoDB (mongoose) using Docker [December 2020]
[App development 0.5] [Node.js express Docker] Build an environment for Node.js Express MongoDB using Docker
[Road _node.js_1-1] Road to build Node.js Express MySQL environment using Docker
Build an Ultra96v2 development environment on Docker 1
Build an environment of "API development + API verification using Swagger UI" with Docker
Build a development environment for Docker + Rails6 + Postgresql
Build a development environment for Docker, java, vscode
[First team development ②] Build an environment with Docker
Try to build a Java development environment using Docker
[2021] Build a Docker + Vagrant environment for using React / TypeScript
I tried to build an environment using Docker (beginner)
Build a local development environment for Open Distro for Elasticsearch with multiple nodes using Docker
Build a Node.js environment with Docker
Build Java development environment (for Mac)
Build Unity development environment on docker
Use MailHog for checking emails in the development environment (using Docker)
Create an app catalog site using CLI for Microsoft 365 with Docker
Build a browser test environment using Capybara in the Docker development environment
Build a development environment for Django + MySQL + nginx with Docker Compose
Build debug environment on container --Build local development environment for Rails tutorial with Docker-
How to build a Ruby on Rails environment using Docker (for Docker beginners)
Build a PureScript development environment with Docker
[Docker] Create Node.js + express + webpack environment with Docker
How to build an environment for any version of Ruby using rbenv
Build an authentication proxy server using Docker
Build a local development environment for Rails tutorials with Docker (Rails 6 + PostgreSQL + Webpack)
Build a Wordpress development environment with Docker
Build an environment with Docker on AWS
Build a simple Docker + Django development environment
[Error resolution] Occurs when trying to build an environment for spring with docker
How to build an environment of [TypeScript + Vue + Express + MySQL] with Docker ~ Vue edition ~
Build a WordPress development environment quickly with Docker
Build a Kotlin app using OpenJDK's Docker container
Build a simple Docker Compose + Django development environment
[Rails] How to build an environment with Docker
Install Ubuntu 20.04 in virtual box on windows10 and build a development environment using docker
How to quit Docker for Mac and build a Docker development environment with Ubuntu + Vagrant
How to build Docker + Springboot app (for basic learning)
How to build docker environment with Gradle for intelliJ
Build an environment of Ruby2.7.x + Rails6.0.x + MySQL8.0.x with Docker
Build Docker + Laravel PHP + Vue.js development environment in 5 minutes
Build Java development environment with WSL2 Docker VS Code
[Docker] Build an Apache container on EC2 using dockerfile
Build an Android image for Orange Pi 4 with Docker
Building an environment for copying the book "Test Driven Development"
How to build [TypeScript + Vue + Express + MySQL] environment with Docker ~ Express ~
I tried to build the environment little by little using docker
How to build Rails, Postgres, ElasticSearch development environment with Docker
Configuration script for using docker in proxy environment on ubuntu 20.04.1