はじめに
Node.jsの公式ページに書いてあることとやっていることはほぼ同じです.
ご了承ください.
大まかな手順
- Node.jsアプリケーションの作成
- Dockerfileの作成
- Dockerイメージをビルドする際に無視するファイルを指定
- Dockerイメージの構築
- Dockerコンテナの起動
- アクセス確認
Node.jsアプリケーションの作成
まずはローカル上にnode.jsアプリケーションを作成します.
作業ディレクトリの作成
Node.jsアプリケーション作成用に新規ディレクトリを作成し,そこに移動します.
$ mkdir ディレクトリ名
$ cd ディレクトリ名
package.jsonの作成
$ touch package.json
package.json
{
"name": "docker_node_js",
"version": "1.0.0",
"description": "Node.js on Docker",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
- 今回はExpress.jsフレームワークを利用します.
npmのバージョンを確認
$ npm --version
- バージョン5以降が推奨(package-lock.jsonが作成されるため)
npm install実行
$ npm install
- npmのバージョンが5以降だと,この実行後に自動的にpackage-lock.jsonが作成される
- パッケージは,node_modulesフォルダ配下にインストールされている
server.jsの作成
package.jsonが配置されているディレクトリに,server.jsを作成する
$ touch server.js
server.js
'use strict';
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
// 指定したポート番号で接続をlistenする
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
- 接続をlistenする,については,こちらを参照
Dockerfileの作成
上記の手順でjsファイルを作成したディレクトリにDockerfileを作成します.
元となるimageの取得
Dockerfile
FROM node:lts
- 今回は,Docker HubにあるNode.jsのimageを元にimageを作成
- タグは,
lts
を選択(lts : long time support)(Laravelのltsについてはこちらを参照)
アプリケーションディレクトリの作成
Dockerfile
WORKDIR /usr/src/app
- image内に,今回のアプリケーションのソースコードを格納するためのディレクトリを作成する
- 絶対パスを使用するのが推奨されている(参考)
アプリケーションに必要なライブラリをインストールする
Dockerfile
COPY package*.json ./
RUN npm install
- 今回使用しているimageには,既にNode.jsとNPMがインストールされているので,その次の段階として必要なパッケージをインストールする
- ワイルドカード(*)を使用することで,package.jsonとpackage-lock.jsonがどちらもコピーされるようにする
-
npm install
に必要なファイルのみをコピーすることで,package.jsonに変更がなかった際にはキャッシュを利用することができるため,処理の負荷を削減することができる*(全てのファイルをコピーしてしまうと,package*.jsonに変更がなくても作業ディレクトリ内のいずれかのファイルので変更があっただけでnpm install
が実行されてしまい,キャッシュを有効利用することができない)
アプリケーションのソースコードをimage内にコピーする
Dockerfile
COPY . .
-
npm install
の処理を走らせた後に,作業ディレクトリの内容をimage内にコピー(バンドル)する
外部に公開するポート番号を指定する
Dockerfile
EXPOSE 8080
- 役割としては,
docker run
コマンド実行時に-p
オプションを指定することと同じ
作成したjsを実行する
Dockerfile
CMD [ "node", "server.js" ]
最終的に完成したDockerfileの中身
Dockerfile
FROM node:lts
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "node", "server.js" ]
Dockerイメージをビルドする際に無視するファイルを指定
.dockerignoreファイル内に,ビルドの際に無視するファイルを指定しておきます.
$ touch .dockerignore
.dockerignore
node_modules
npm-debug.log
- この記述をすることにより,ローカルにインストールされたモジュールやデバッグログがDockerイメージ上にコピーされたり,イメージ上のモジュールが上書きされてしまったりするのを防ぐ.
Dockerイメージの構築
作成したDockerfileを元にイメージをビルドしていきます.
$ docker build -t node_tutorial:latest .
-
-t
:名前:タグ
の形式で記述することで,イメージに名前とタグをつけることができる
作成されたイメージの確認
$ docker images node_tutorial:latest
Dockerコンテナの起動
$ docker run -p 49160:8080 -d node_tutorial:latest
-
-p
: server.js内で指定したポートとlocalhostのポートを紐づける(localhostのポート:Dockerコンテナのポート) -
-d
: バックグラウンドで起動
実行しているDockerイメージの確認
$ docker ps
アクセス確認
$ curl -i localhost:49160
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
...
Hello, World!
-
-i
: ResponseのHeader,Bodyを両方とも出力する
ログの確認
$ docker logs node_container
Running on http://0.0.0.0:8080