Node.js ウェブ・アプリの Docker 化

この例のゴールは、 Dockerfile を使い、親イメージから自分の Docker イメージを構築できるようにする方法をみていきます。ここでは CentOS 上で簡単な Node.js の hello world ウェブ・アプリケーションを実行します。ソースコード全体は https://github.com/enokd/docker-node-hello/ から入手できます。

Node.js アプリの作成

まず、すべてのファイルを置く src ディレクトリを作成します。それから package.json ファイルを作成し、アプリケーションと依存関係について記述します。

{
  "name": "docker-centos-hello",
  "private": true,
  "version": "0.0.1",
  "description": "Node.js Hello world app on CentOS using docker",
  "author": "Daniel Gasienica <daniel@gasienica.ch>",
  "dependencies": {
    "express": "3.2.4"
  }
}

次に index.js ファイルを作成し、ウェブアプリが Express.js フレームワークを使うように定義します。

var express = require('express');

// Constants
var PORT = 8080;

// App
var app = express();
app.get('/', function (req, res) {
  res.send('Hello world\n');
});

app.listen(PORT);
console.log('Running on http://localhost:' + PORT);

In the next steps, we’ll look at how you can run this app inside a CentOS container using Docker. First, you’ll need to build a Docker image of your app.

次のステップでは、Docker が CentOS コンテナの中で、どのようにこのアプリを実行するかをみていきます。まず、自分のアプリを動かす Docker イメージを作成します。

Dockerfile の作成

Dockerfile という名称の空ファイルを作成します。

touch Dockerfile

好みのエディタで Dockerfile を開きます。

自分のイメージの構築に使いたい親イメージを定義します。ここでは Docker Hub 上で利用可能な CentOS (タグ: centos6 )を使います。

FROM    centos:centos6

Node.js アプリを作りたいので、CentOS イメージ上に Node.js と npm のインストールをします。アプリケーションの実行に Node.js が必要です。また、 package.json で定義したアプリケーションをインストールするために npm も必要です。CentOS 用の適切なパッケージをインストールするため、 Node.js wiki の指示に従って作業します。

# Enable Extra Packages for Enterprise Linux (EPEL) for CentOS
RUN     yum install -y epel-release
# Install Node.js and npm
RUN     yum install -y nodejs npm

npm バイナリでアプリケーションの依存関係をインストールします。

# Install app dependencies
COPY package.json /src/package.json
RUN cd /src; npm install

アプリケーションのソースコードを Docker イメージに取り込むため、 COPY 命令を使います。

# Bundle app source
COPY . /src

アプリケーションはポート 8080 を利用するため、 EXPOSE 命令を使い docker デーモンがポートを割り当てるようにします。

EXPOSE  8080

最後にあと少し、実行時にアプリケーションが実行できるよう CMD 命令でコマンドを定義します。例えば node と、アプリケーション、例えば src/index.js を指定します(ソースファイルは前の手順でコンテナに加えていました)。

CMD ["node", "/src/index.js"]

これで Dockerfile は次のようになります。

FROM    centos:centos6

# Enable Extra Packages for Enterprise Linux (EPEL) for CentOS
RUN     yum install -y epel-release
# Install Node.js and npm
RUN     yum install -y nodejs npm

# Install app dependencies
COPY package.json /src/package.json
RUN cd /src; npm install

# Bundle app source
COPY . /src

EXPOSE  8080
CMD ["node", "/src/index.js"]

イメージを構築

Dockerfile のあるディレクトリに移動し、Docker イメージを構築するため次のコマンドを実行します。 -t フラグを使いイメージにタグを付けておくと、あとから docker images コマンドで簡単に探せます。

$ docker build -t <your username>/centos-node-hello .

作成したイメージは、Docker のイメージ一覧に表示されます。

$ docker images

# Example
REPOSITORY                          TAG        ID              CREATED
centos                              centos6    539c0211cd76    8 weeks ago
<your username>/centos-node-hello   latest     d64d3505b0d2    2 hours ago

イメージの実行

イメージに -d を付けて実行すると、コンテナはデタッチド・モードで動作します。これは、コンテナをバックグラウンドで動作するものです。 -p フラグで、コンテナ内のプライベートなポートを公開ポートに渡します。

$ docker run -p 49160:8080 -d <your username>/centos-node-hello

アプリケーションの出力を表示します。

# Get container ID
$ docker ps

# Print app output
$ docker logs <container id>

# Example
Running on http://localhost:8080

テスト

To test your app, get the port of your app that Docker mapped:

アプリケーションをテストするには、Docker でアプリケーションにポートを割り当てます。

$ docker ps

# Example
ID            IMAGE                                     COMMAND              ...   PORTS
ecce33b30ebf  <your username>/centos-node-hello:latest  node /src/index.js         49160->8080

上記の例では、Docker はコンテナのポート 8080 をポート 49160 に割り当てています。

これで curl を使ってアプリケーションを呼び出せます(必要があれば sudo apt-get install curl でインストールします。 )。

$ curl -i localhost:49160

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
Date: Sun, 02 Jun 2013 03:53:22 GMT
Connection: keep-alive

Hello world

OS X 上で Docker Machine を使っているのであれば、ポートが実際に割り当てられているのは Docker ホストの VM 側であり、次のコマンドを使う必要があります。

$ curl $(docker-machine ip VM_NAME):49160

私たちはこのチュートリアルが Docker 上で Node.js と CentOS を動かすための手助けになればと望んでいます。全てのソースコードは https://github.com/enokd/docker-node-hello/ にあります。