【Docker】コンテナ落とすのになんでこんな時間かかるん?Tiniを使って解決した話
はじめに 🐳
Dockerを使ってアプリケーションを動かしていると、
「コンテナが docker stop
でうまく終了しない…😰」
「なんか終了されるまでに10秒くらいかかってない。。?🤔」
といった現象に遭遇することがあります。
もしかしたら、PID 1 が原因かもしれません。
今回は、
- DockerコンテナにおけるPID 1の特殊な挙動
- なぜNode.jsがPID 1だと問題が起こるのか
- 解決策としてのTini
について、調べたことをまとめていきます!
なんで終了までに時間がかかるのか? ⏳
Dockerコンテナ内で Node.js アプリケーションを動かす とき、node app.js
のように CMD ["node", "app.js"]
で起動するケースが多いです。
この場合、Node.js のプロセス(node app.js
)がコンテナ内でPID 1として実行されます。
しかし、Node.js は本来PID 1 として動作するように設計されていないため、SIGTERM を受け取らず、正常に終了できません。
docker stop
を実行すると、以下の流れになります。
- Dockerはコンテナ内のPID 1に
SIGTERM
を送信 - Node.jsはPID 1だと
SIGTERM
を無視してしまう - Dockerは 10秒間待機
- それでも終了しない場合、強制的に SIGKILL を送信
そのため、コンテナの終了に 10秒かかってしまう という現象が発生します。
そもそもPIDとは? 🔢
PID(Process ID)とは、LinuxやUnix系OSで動作するプロセスを識別するための番号です。
- PID 1 は、システムの最初のプロセスに割り当てられる特殊なID
- OS起動時に
init
やsystemd
などのプロセスがPID 1として動作し、すべての子プロセスを管理 - Dockerコンテナでは、最初に起動したプロセスがPID 1になる
Dockerコンテナ内で node app.js
のように実行すると、Node.jsがPID 1として動作するため、通常の環境とは異なる挙動になることがあります。
解決策 🏆
Node.jsを使用しているコンテナには、init: true
を指定して、Tiniを使うと解決できます。
Docker Composeの場合
compose.yml
などのファイルに、下記のようにinit: true
を追加します。
version: '3'
services:
app:
image: my-node-app
init: true
Dockerfileで設定する場合
Docker Composeを使わない場合は、Dockerfileに tini
を明示的に追加できます。
FROM node:18-alpine
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "app.js"]
なぜinit: trueを指定すると解決するのか? 🤔
Tiniが以下の役割を果たすため解決できます。
- プロセスのシグナルを適切に処理
- ゾンビプロセスの処理
- 子プロセス(Node.js)へのシグナルの適切な転送
init: true とは? 🛠️
Docker Compose で init: true
を指定すると、自動的に Tini という軽量な init システムが組み込まれ、PID 1として動作するようになります。
init: true
を指定するだけでTiniが動くのか?
なぜ Dockerは init: true
が指定されると、内部で Tiniを組み込んでコンテナのエントリポイントをTini経由に変更 します。
そのため、特別な設定なしに Tini の機能を利用できます。
version: '3'
services:
app:
image: my-node-app
init: true // ここを追加
restart: always
この設定を追加すると、
- TiniがPID 1となり、適切にシグナルを処理する
-
Node.jsはPID 2になり、SIGTERMを正しく受け取る
という状態になるため、正常にdocker stop
できるようになります。
ちなみにTiniとは? 🔍
Tiniは Dockerコンテナ内のPID 1の問題を解決するための超軽量なinitプロセス です。
Tiniの特徴
✅ 超軽量(バイナリサイズ約 10KB、CPU/メモリほぼ消費なし)
✅ シグナルを適切に処理(SIGTERM / SIGINT を正しく伝播)
✅ ゾンビプロセスを防ぐ(wait() を実行)
まとめ ✍️
- DockerコンテナにおけるPID 1の特殊な挙動
- なぜNode.jsがPID 1だと問題が起こるのか
- 解決策としてのTini
について、調べたことをまとめていきました。
記事を読んでいただきありがとうございました!
Discussion