Node チュートリアル - 開発環境構築

Node, express, mongoDbを勉強したかったので、Dockerで開発環境を作ってみた。




# ディレクトリ構造
```
docker-compose.yml
docker-configs/lerning-node/Dockerfile
docker-configs/mongo/mongod.conf
docker-configs/mongo/Dockerfile
apps/Learning_Node/package.json
apps/Learning_Node/app.js
```

# docker-compose.yml

```
version: '2'
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    ports:
      - '80:80'
      - '443:443'

  mongo:
    build: ./docker-configs/mongo
    restart: always
    ports:
      - "27017:27017"
    volumes:
      - ./data/mongodb/db:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: admin

  learning-node:
    build: docker-configs/learning-node
    volumes:
      - ./apps/Learning_Node:/var/www/html
    depends_on:
      - mongo
    environment:
      - VIRTUAL_HOST=learning-node.local.host
      - COLUMNS=200
```

# docker-configs/learning-node/Dockerfile

```
FROM node:10.16.3

WORKDIR /var/www/html
EXPOSE 80
CMD [ "npm", "start" ]
```

# docker-configs/mongo/Dockerfile

```
FROM mongo:4.2.0

COPY ./mongod.conf /etc/mongod.conf
```

# docker-configs/mongo/mongod.conf

```
security:
    authorization: enabled
```

# package.json

```
{
  "name": "learning-node",
  "version": "1.0.0",
  "description": "For learning Node Js.",
  "author": "Shintaro Nitta",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  },
  "scripts": {
    "start": "node app.js"
  }
}
```


# Install Node Js

```
nodebrew install v10.16.3
nodebrew use v10.16.3
node --version
```

# npm install, run docker-compose

```
cd apps/Learning_Node
npm install
cd ../
docker-compose up -d
```

# Add a host to /etc/hosts, access the host
```
127.0.0.1 learning-node.local.host
```

# app.js

```
const express = require('express');
const { config, engine } = require('express-edge');
const router = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
require('date-utils');

const viewFolder   = __dirname + '/views/';
const documentRoot = __dirname + '/public/';
const port         = 80;
const app          = new express();
const Post         = require('./database/models/Post');

// Initialize Middlewares.
mongoose.connect('mongodb://node-blog:password@mongo:27017/node-blog', { useNewUrlParser: true, auth:{authdb: "node-blog"}})
    .then(() => 'You are now connected to Mongo!')
    .catch(err => console.error('Something went wrong', err))
app.use(express.static('public'));
app.use(engine);
app.set('views', viewFolder);
app.use(bodyParser.json())

app.use(bodyParser.urlencoded({
    extended: true
}));

// Configure Edge if need to.
config({ cache: process.env.NODE_ENV === 'production' });

// Load middleware function that will log requests.
router.use(function (req, res, next) {
    let date = new Date();
    console.log('Time:', date.toFormat("YYYY/MM/DD HH24:MI:SS"));
    // Take over to a router.
    next();
});

router.get('/', (req, res) => {
    res.render('index');
});

router.get('/about', (req, res) => {
    res.render('about');
});

router.get('/contact', (req, res) => {
    res.render('contact');
});

router.get('/post', (req, res) => {
    res.render('post');
});

router.get('/posts/new', (req, res) => {
    res.render('create');
});

app.post('/posts/store', (req, res) => {
    console.log(req.body);
    Post.create(req.body, (error, post) => {
        console.log(error, post);
        res.redirect('/posts/new');
    });
});

app.use(express.static(documentRoot));
app.use('/', router);
app.listen(port, function () {
    console.log('Example app listening on port 80!')
});
```

# Run docker-compose & create mongodb user

```
docker-compose up -d
docker exec -it <mongo_container_name> bash

# mongo -u root
MongoDB shell version v4.2.0
Enter password:

> use node-blog
> db.grantRolesToUser('node-blog', [{role: 'readWrite', db: 'node-blog'}])
> db.grantRolesToUser('node-blog', [{role: 'dbAdmin', db: 'node-blog'}])
```
Note: Basically `readWrite` provides CRUD, `dbAdmin` provides database management ability.