わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

DockerとNode.jsで「Hello, world!」のWebサーバ

3年生に与えたゼミの課題で,1人からメールで問い合わせが来ました.その質問に答えるにあたり,Node.jsを使用した単純なWebサーバのDockerイメージを作ってみました.
まず,ディレクトリ~/nodesimplewebserverを作ってそこに移動し,以下の内容のDockerfileを作成しました.

FROM node:9
EXPOSE 1337
WORKDIR /root
COPY ["server.js", "/root"]
CMD ["node", "server.js"]

「node:9」と書いた,ベース・イメージについては,https://hub.docker.com/_/node/ を参照して決めました.このバージョンのDockerfileを読むと,最初は「FROM buildpack-deps:jessie」とあり,jessieということでDebianなのが推測できます.
もう一つ,用意しておかないといけないのは,server.jsです.Webサーバ+アプリ構築が速すぎる件 〜 JSおくのほそ道 #004 - Qiitaのhosoweb.jsを参考にして,以下のとおりとしました.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello, world!\n');
}).listen(1337);

listenの引数が,サーバのポート番号です.1337が慣例らしいです.元記事ではlistenに第2引数を指定していますが,課題のもとになるファイル(非公開)に合わせて,引数は1つだけにしました.
「docker build -t nodesimplewebserver .」でビルドを行い,「docker run -d --rm -p 1337:1337 --name nodeserver nodesimplewebserver」でコンテナを起動して,ブラウザで,http://localhost:1337/ にアクセスすると,無事に「Hello, world!」が表示されました.「docker stop nodeserver」で終了の際,数秒を要しました.
このサーバ1つで,Dockerイメージは何MBになるんだろうと思いながら,「docker images | grep node」を実行してみました.

nodesimplewebserver latest 5a5b8fdcb68f 4 minutes ago 676MB
node 9 c888d933885c 13 days ago 676MB
node latest c888d933885c 13 days ago 676MB
node alpine 04a3ba95f191 2 months ago 64.6MB

676MBにもなるのか,サイズでかいなあ…と思った次に,最終行に目が留まりました.2か月前に何かでpullした,「node:alpine」だと,その10分の1以下のサイズになっているのです.
Dockerfileを書き換えました.

FROM node:9-alpine
EXPOSE 1337
WORKDIR /root
COPY ["server.js", "/root"]
CMD ["node", "server.js"]

ビルド,コンテナ起動,ブラウザでアクセス,コンテナ停止も,問題なく行えました.
再度,「docker images | grep node」を実行してみました.

nodesimplewebserver latest 19c6a5614dc5 3 seconds ago 68MB
node 9-alpine b5f94997f35f 13 days ago 68MB
node 9 c888d933885c 13 days ago 676MB
node latest c888d933885c 13 days ago 676MB
node alpine 04a3ba95f191 2 months ago 64.6MB

68MBで済みました.
10分足らずの出来事でしたが,ベース・イメージ選択の重要性とともに,なぜDockerでAlpine Linuxが好んで使われるのかを知ることになった一件でした.