Node.jsをDockerで動かすときのPID 1問題について動作確認する

概要

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

Docker/Kubernetes で PID 1 問題を回避する | text․superbrothers․dev