概要
Node.jsとDockerのPID1問題について動作確認する。
結論
Dockerでnodeプロセスを動かす場合
- 直接動かすときはtiniやdocker run --initオプションを使う
- npmを使って起動しない
確認
下記のようなファイルを用意する
$ls
Dockerfile server.js
Dockerfile
FROM node COPY . . EXPOSE 3000 CMD ["node", "server.js"]
server.js
require("http") .createServer(function (request, response) { response.end("test"); }) .listen(3000);
イメージ作成
$docker build -t node-pid .
コンテナ起動
$docker run node-pid
起動確認
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c446d9f1d8be node-pid "docker-entrypoint.s…" 8 seconds ago Up 7 seconds inspiring_margulis
プロセスを止める
$docker kill -s TERM c446d9f1d8be
確認
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c446d9f1d8be node-pid "docker-entrypoint.s…" 8 seconds ago Up 7 seconds inspiring_marguli
すぐにはコンテナが停止せずに残っていることが確認できる。
対応
tiniを利用する
GitHub - krallin/tini: A tiny but valid `init` for containers
Dockerfileを下記のように変更する。
FROM node COPY . . ENV TINI_VERSION v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini EXPOSE 3000 ENTRYPOINT ["/tini", "--"] CMD ["node", "server.js"]
ビルド
$docker build -t node-pid-tini .
起動
$docker run node-pid-tini
確認
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fd19dacfb23b node-pid-tini "/tini -- node hello…" 5 seconds ago Up 4 seconds 3000/tcp stoic_galois node-pid
プロセスを止める
$docker kill -s TERM fd19dacfb23b fd19dacfb23b
確認
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
停止することが確認できた。
initオプションを利用する
Docker run reference | Docker Documentation
FROM node COPY . . EXPOSE 3000 CMD ["node", "server.js"]
起動
$docker run --init node-pid
確認
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4a01d8a4b1e9 node-pid "docker-entrypoint.s…" 8 seconds ago Up 7 seconds angry_yonath
プロセスを止める
$docker kill -s TERM 4a01d8a4b1e9
確認
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
停止することが確認できた。
参考
Docker で node.js を動かすときは PID 1 にしてはいけない - ngzmのブログ
docker-node/BestPractices.md at master · nodejs/docker-node · GitHub