Node.js(express+ejs)のWebアプリサンプルをDocker上で動かす

# はじめに
* Node.jsをDockerで起動し、適当なWeb画面を表示させるところまでをやります
* Node.jsでのサンプルは[Akinari Tsugoさんの記事](https://garafu.blogspot.com/2016/07/nodejs-express-webapp-tutorial.html)を参考に実装しました

# やったこと
* Node.js（express + ejs）の環境をdockerで構築する 
* express + ejsを使用したWebアプリサンプルを作成し、docker上で起動させる

# 使用するフレームワークについて
## expressとは
* Node.jsでWebアプリを開発する際に使用するフレームワーク
* 画面遷移とかWebアプリ開発に必要な諸々をサポートする機能あり
* [expressの公式はこちら](https://expressjs.com/)

## ejsとは 
* JavaScriptでHTMLを作成できるテンプレート言語
* JavaでいうところのJSPに相当する
* [ejsの公式はこちら](https://ejs.co/)


# node.jsをdockerで構築する
## Dockerfileの作成
* 鉄板のalpineを選択
* express、ejsのみをnpmで投入

```Docker
FROM node:alpine

RUN npm install express
RUN npm install ejs

# 作業ディレクトリへ移動
WORKDIR /app

# 3000番ポートを公開
EXPOSE 3000
```

## docker-compose.ymlの作成
* volumesの設定など、何かとdocker-composeにしておいた方がいいのでdocker-compose.ymlを作成
* ```tty: true```としておくことで、コンテナをずっと起動状態にできる
* ```build: .```でDockerfileの位置を指定
* ```volumes:```の指定で、コンテナ内の```/app```をホスト側にもマウント

```Docker
version: '3'
services:
  app:
    build: .
    tty: true
    container_name: node-sample01
    volumes:
      - ./app:/app
    ports:
      - "8080:3000"

```


# Webアプリサンプル
## ディレクトリ構成
* ディレクトリ全体構成は以下の通り

```
app/
　├ public/
　│　└ 静的なファイル群
　├ routes
　│　└ index.js
　├ views
　│　└ index.ejs
　└ app.js
Dockerfile
docker-compose.yml
```

## app.js

```JavaScript
var express = require('express');
var app = express();
 
// テンプレートエンジンをEJSに設定
app.set('views', './views');
app.set('view engine', 'ejs');
 
// public配下の静的ファイルは無条件に公開
app.use('/public', express.static('public'));
 
// URLと処理をマッピング
app.use('/', require('./routes/index.js'));
 
// ポート3000で起動
app.listen(3000);
 
// アプリケーション開始時のログ
console.log('Server running at http://localhost:3000');
```

## index.js

```JavaScript
var express = require('express');
var router = express.Router();
 
// デフォルトルーティング
router.get('/', function (request, response) {
    // パラメータに値を設定、設定したパラメータはejs内で参照可能となる
    response.render('index', { title: 'NodeSample01', message: 'Hello Node.js' });
});
 
module.exports = router;
```

## index.ejs
* index.jsで設定した```title```と```message```をejs内で参照

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><%= title %></title>
    <link rel="stylesheet" href="/public/bootstrap/bootstrap.css" />
    <link rel="stylesheet" href="/public/css/index.css" />
    <script type="text/javascript" src="/public/jquery/jquery.js"></script>
    <script type="text/javascript" src="/public/bootstrap/bootstrap.js"></script>
   	<script type="text/javascript" src="/public/js/index.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Hello Project</a>
        </div>
      </div>
    </nav>
 
    <div class="container">
      <div class="starter-template">
        <p><%= message %></p>
        <p><img id="img" src="/public/images/drum.jpg" class="img-thumbnail"></p>
      </div>
    </div> 
  </body>
</html>
```

## 起動方法
* ```docker-compose up```にてコンテナを起動したら、以下でコンテナにログイン

```sh
docker exec -it node-sample01 /bin/ash
```
* コンテナ内でNode.jsを起動

```
node app.js
```

## サンプル画面の表示
* ```http://localhost:8080```で以下画面が表示される
![NodeSample01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310068/e848bebf-c762-661c-c09f-5f3e7375d061.png)