Docker で Node.js(Express)アプリケーションを動かす


学習がてらやってみたのでメモ。

### 作業環境

> OS：`Mac OS X 10.9.5`
> Docker：`1.6.2`

前提として、Mac への Docker のセットアップは完了しているものとします。

また Docker のイメージはこれ(たぶん公式)を使います。
⇒ https://registry.hub.docker.com/_/node/

# 手順

## Docker イメージの動作確認

まずは Node.js 用の Docker イメージ(公式)がきちんと動くか確認してみます。イメージ名は `node` のようです。

```shell:
$ docker run -it node /bin/bash
```

> 初回はローカルにイメージをダウンロードするため時間がかかります。

接続したら、Node.js のバージョンを表示してみます。

```shell:
# node -v

v0.12.4
```

> `$ docker run` コマンドで利用できるオプションは `$ docker help run` で確認できます。

## Node.js(Express)アプリケーションの用意

適当にプロジェクト用のディレクトリを作り `$ npm init` します。

```
$ mkdir express_app
$ cd express_app
$ npm init
```

質問に適当に答えます。

![スクリーンショット 2015-06-12 16.46.32.png](https://qiita-image-store.s3.amazonaws.com/0/35733/ebeda563-6b1a-5a80-3e11-4bc253579ad8.png "スクリーンショット 2015-06-12 16.46.32.png")

すると `package.json` が作成されます。

```json:package.json
{
  "name": "express_app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

好みに応じて修正します。私の場合は次のとおり。

```json:package.json
{
  "name": "express_app",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "MIT"
}
```

次に Express(Node.js 用のフレームワーク) を導入します。

```shell:
$ npm install --save express
```

すると `node_modules` ディレクトリ配下に Express がインストールされ `package.json` にも Express が追記されます。

![スクリーンショット 2015-06-12 16.57.12.png](https://qiita-image-store.s3.amazonaws.com/0/35733/a69293a6-f059-4d33-dd0b-c6db56615598.png "スクリーンショット 2015-06-12 16.57.12.png")

`package.json` と同じ階層に、静的ファイル用の `public` ディレクトリも一応、作っておきます。また同じ階層に `index.js` を新規に作成します。

![スクリーンショット 2015-06-12 16.59.53.png](https://qiita-image-store.s3.amazonaws.com/0/35733/a3fd174b-3197-d026-1574-82fa089aa0aa.png "スクリーンショット 2015-06-12 16.59.53.png")

`index.js` には次のように記載します。

```javascript:index.js
var express = require('express');
var app = express();

app.set('port', 5000);
app.use(express.static(__dirname + '/public'));

app.get('/', function(request, response) {
  response.send('Hello World!')
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'))
});
```

> `app.set()` で設定しているポート番号(今回は`5000`)は何でもいいです。

もし手元の作業環境に Node.js がインストールされている場合、ここで一旦、動作確認します。アプリケーションを起動し、

```shell:
$ node index.js
```

ブラウザで `http://localhost:5000` へアクセスしてみます

![スクリーンショット 2015-06-12 17.05.06.png](https://qiita-image-store.s3.amazonaws.com/0/35733/f6c5d276-cf33-d416-35d0-ec42227812e1.png "スクリーンショット 2015-06-12 17.05.06.png")

## Docker で Node.js(Express)アプリケーションを動かしてみる

先ほどのプロジェクト用のディレクトリ直下へ移動し、Docker を立ち上げます。

```shell:
$ cd express_app
$ docker run -it -v `pwd`:/tmp -p 8080:5000 node /bin/bash
```

> `-v` オプションにより、現在いる場所(プロジェクト用のディレクトリ)を、Docker 内の `/tmp` へマウントしています。また `-p` オプションにより、作業環境(Mac)のポート `8080(任意)` を `5000(index.jsに設定したポート番号)` へ転送しています。

接続したら、アプリケーションを起動します。

```shell:
# node /tmp/index.js
```

ブラウザで Docker ホストの IP の、先ほど指定したポートへアクセスしてみます。

![スクリーンショット 2015-06-12 17.08.42.png](https://qiita-image-store.s3.amazonaws.com/0/35733/d8b4cd4d-1c7a-34e7-fe70-f1da41487d13.png "スクリーンショット 2015-06-12 17.08.42.png")

> 上記の Docker ホストの IP は、環境によって異なるかもしれません。`$ boot2docker ip` で調べることができます。

# おわりに

Docker 便利そうなので、他にもいろいろ試してみようと思います。