LoginSignup
8
8

More than 5 years have passed since last update.

Docker上にExpressの最初構成を整えるまでの全て

Last updated at Posted at 2017-03-13

これの続き

環境

  • OS X El Capitan 10.11.6
  • Docker 17.03.0-ce-mac2
  • Express 4.15.2

前回までのディレクトリ構成

jumpage/
  ├ app/
  |  ├ node_modules/
  |  ├ index.js
  |  └ package.json
  ├ scripts/
  |  └ docker_run.sh
  └ Dockerfile

手順

Expressのプロジェクトを新規作成する

  • ホスト側で実行
cd jumpage
sh scripts/docker_run.sh
  • コンテナ側で実行
cd app
# 前回作ったソースファイルを削除
rm -rf ./*
# express-generatorを使って新規作成
express jumpage

JadeをPugにする

  • 2017年3月時点では、express-generatorではテンプレートエンジンのデフォルトがJadeだった
  • Jadeは、Jade Software Corporationと名前が被ったので、Pugにリネームされた
  • Pugという名前に慣れるために、以下の記事を参考に、JadeをPugにする
  • 手順
    • app.js内のテンプレートエンジンの指定をjade->pugに変更
    • views/以下のjadeファイルの拡張子をpugに変更
    • package.jsonのjadeを削除
    • コンテナ側で以下を実行 cd jumpage npm install --save pug@2.0.0-beta11 # package.jsonのその他のモジュールをインストール npm install

コンテナ内からサーバーを立ち上げてみる

npm start

自動生成されたファイル群を眺める

  • 新しいディレクトリ構成
jumpage/
  ├ app/
  |  └ jumpage
  |    ├ app.js
  |    ├ bin
  |    |  └ www
  |    ├ public
  |    |  ├ images/
  |    |  ├ javascripts/
  |    |  └ stylesheet/
  |    ├ routes
  |    |  ├ index.js
  |    |  └ users.js
  |    ├ views
  |    |  ├ index.pug
  |    |  ├ layout.pug
  |    |  └ error.pug
  |    ├ node_modukes
  |    └ package.json
  ├ scripts/
  |  └ docker_run.sh
  └ Dockerfile
  • app.jsがやっていることを理解する
app.js
// モジュールを読み込む
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

// ./routes以下のファイルを読み込む
var index = require('./routes/index');
var users = require('./routes/users');

var app = express();

// テンプレート格納ディレクトリを教える
app.set('views', path.join(__dirname, 'views')); // __dirnameは、このファイルのパス
// テンプレートエンジンをpugに指定
app.set('view engine', 'pug');

// faviconを使うときはコメント外す
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
// devモードでログを吐き出す
app.use(logger('dev'));
// リクエストのbodyをパースする設定
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// cookieパースの設定
app.use(cookieParser());
// 静的ファイル(js, img, css)の格納ディレクトリを教える
app.use(express.static(path.join(__dirname, 'public')));

// ルーティングの設定(./routes/index.jsなどに飛ばす)
app.use('/', index);
app.use('/users', users);

// 上のルーティングに当てはまらなかった場合、404を設定
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// エラーぺージの出力
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;
  • bin/wwwがやっていることを理解する
www
#!/usr/bin/env node

/**
 * 依存モジュールを読み込む
 */

var app = require('../app'); // 上で読んだ、app.js
var debug = require('debug')('jumpage:server');
var http = require('http');

/**
 * envファイルがあれば、そこからポート番号を設定する(デフォルトは3000)
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * HTTPサーバを生成
 */

var server = http.createServer(app);

/**
 * 設定したポート番号でリクエストを受け付ける
 */

server.listen(port);
// エラー時はonError()を呼ぶ
server.on('error', onError);
// listen成功時はonListening()を呼ぶ
server.on('listening', onListening);

/**
 * 正しいポート番号かfalseを返す
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * エラー処理(適切なログを吐き出す)
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * 正常系処理(適切なログを吐き出す)
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
  • package.jsonを読む
    • npm start時は、scripts.startのコマンドが実行される
package.json
{
  "name": "jumpage",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.16.0",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.0",
    "express": "~4.14.1",
    "pug": "~1.11.0",
    "morgan": "~1.7.0",
    "serve-favicon": "~2.3.2"
  }
}

参考記事

ここまでのディレクトリ構造(再掲)

jumpage/
  ├ app/
  |  └ jumpage
  |    ├ app.js
  |    ├ bin
  |    |  └ www
  |    ├ public
  |    |  ├ images/
  |    |  ├ javascripts/
  |    |  └ stylesheet/
  |    ├ routes
  |    |  ├ index.js
  |    |  └ users.js
  |    ├ views
  |    |  ├ index.pug
  |    |  ├ layout.pug
  |    |  └ error.pug
  |    ├ node_modukes
  |    └ package.json
  ├ scripts/
  |  └ docker_run.sh
  └ Dockerfile

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8