【アプリ開発 0.5】【Node.js express Docker】 Dockerを用いてNode.js Express MongoDBの環境を構築する

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

↓ こちらに、本記事の改訂版(mongooseを使用するバージョン)があります。
[【アプリ開発 １】【Node.js express Docker】 Dockerを用いてNode.js Express MongoDB(mongoose)の環境を構築する【2020年12月】]
(https://qiita.com/sho_U/items/43f6483aac8ca45a12f6)

##Node.js Express MongoDBを用いたアプリ開発
受託開発でNode.js Express MongoDBを用いたアプリ開発を行うことになりました。
開発の中で得られた知見を、支障のない範囲で記録していきたいと思います。
アプリの内容はさておき、チームで開発するため、まずはDockerを用いて開発環境を構築を行います。

###構築する環境

- docker-composeを用いて、アプリコンテナ、mongodbコンテナを作成する。
- アプリコンテナとmongodbコンテナの接続テスト(mongoose)を用いて、テストモデルにデータ保存。
- mongo compassからデータの挿入を確認
- mongodbに認証を設ける。作成するユーザーの権限は"root","read","owner"
- データベース様パスワード等は環境変数で管理(gitignoreにてgitの管理から外す。)

###初期インストールするパッケージ一覧

```
 "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"
```
###最初に用意するファイル群

```
.
├── .env
├── .gitignore
├── Dockerfile
├── data
│   └── db  //空ディレクトリ
├── docker-compose.yml
├── docker_app
│   └── Dockerfile
├── secret_file
│   ├── db.env
│   └── db_init
└── src
    ├── controllers
    │     └── initTestsController.js
    ├── models
    │     └── init_test.js
    └── package.json

```

.env


docker-compose build
docker-compose up -d
docker exec -it uniq_app_cnt bash

npx express-generator --view=ejs

package.json貼り付け

npm install






##最初に用意するパッケージ

```
├── Dockerfile
├── data
│   └── db
├── docker-compose.yml
├── src
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   └── test_db.js
├── .env
└── .gitignore
```

```Dockerfile.
FROM node:12
WORKDIR /app
RUN npm install
```

```docker-compose.yml
version: '3'
services:
  app:
    build: .
    container_name: <アプリ名>_app_cnt
    ports:
      - 8080:8080
    restart: always
    working_dir: /app
    tty: true
    volumes:
      - /etc/passwd:/etc/passwd:ro
      - /etc/group:/etc/group:ro
      - ./src:/app
    command: bash
    networks:
      - <アプリ名>-network
    depends_on:
      - mongo
  mongo:
    image: mongo:4.2.5-bionic
    container_name: <アプリ名>_db_cnt
    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
    command:
      - mongod
    networks:
      - <アプリ名>-network
networks:
  <アプリ名>-network:
    external: true
```

```.env.
APP_USER=hoge
MONGO_INITDB_ROOT_USERNAME=test
MONGO_INITDB_ROOT_PASSWORD=pass
MONGO_INITDB_DATABASE=testdb
```

```.gitignore.
node_modules/
data/
.env
```
```test_db.js
const mongodb = require('mongodb')
const MongoClient = mongodb.MongoClient

let url = 'mongodb://test:pass@mongo:27017/'
let db_name = 'testdb'
let collection_name = 'testUser'

console.log(url)
console.log(db_name)
console.log(collection_name)

const option = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
}

MongoClient.connect(url, option, (err, client) => {//mongodb接続
  if (err != null || client == null) {
    console.log("<<<ログ>>>fail")
    console.log(err)
  } else {
    const db = client.db(db_name)
    let rec = { "name": "Taro", "age": 30 }
    db.collection(collection_name).insertOne(rec, (err, res) => {//テストデーター挿入
      if (err != null) {
        console.log("<<<ログ>>>err: insert")
        console.log(err)
        client.close()
      } else {
        db.collection(collection_name).find({}).toArray((err, result) => {//データー取り出し
          if (err != null) {
            console.log("<<<ログ>>>err: select")
            console.log(err)
            client.close()
          } else {
            console.log(result)//結果出力
            client.close()
          }
        })
      }
    })
  }
})
```
```
docker-compoes up
```
接続確認。

ターミナル別タブ開きアプリのディレクトリに移動

```
docker exec -it <アプリ名>_app_cnt bash
//コンテナ内に入る
node test_db
```
テストデーターの挿入、取り出しを確認

```
testdb
testUser
[ { _id: 5fe60041416135000e5cd787, name: 'Taro', age: 30 } ]
```
接続完了