目次
Docker コンテナのライフサイクル入門:作成、起動、停止、削除
コンテナは作成から削除まで、いくつかの状態を経ます。これらの状態を理解すると、コンテナが「少し動いただけですぐ止まる」ことがある理由、停止したコンテナが名前を使い続ける理由、docker stop が 10 秒待つことがある理由がわかります。
コンテナの状態
| 状態 | 意味 | docker ps -a の STATUS |
|---|---|---|
created | 作成済みだが、まだ起動していない | Created |
running | メインプロセスが実行中 | Up 3 minutes |
paused | すべてのプロセスが凍結されている | Up 3 minutes (Paused) |
exited | メインプロセスは終了したが、コンテナは残っている | Exited (0) 10 seconds ago |
restarting | 再起動ポリシーに従って再起動中 | Restarting (1) 2 seconds ago |
Exited の後ろの括弧内の数字はメインプロセスの終了コードです。0 は正常終了を表します。詳しくは後述します。
コンテナが停止するタイミング
コンテナのライフサイクル = メインプロセス(PID 1)のライフサイクルです。 メインプロセスが終了すると、コンテナも停止します。
よくある疑問について説明します。
$ docker run ubuntu:26.04
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66e6f85c66e0 ubuntu:26.04 "/bin/bash" Less than a second ago Exited (0) Less than a second ago dreamy_solomon
docker run ubuntu:26.04 は何も出力せずに終了し、docker ps にも表示されません。docker ps -a を使うと、メインプロセスが /bin/bash であることを確認できます。しかし -it を付けていないため、bash は読み取る入力がなく、起動直後に終了します。そのため、コンテナも停止します(Exited (0))。
-it を付けて対話型ターミナルを割り当てると、bash は入力を待ち続けます。
docker run -it ubuntu:26.04
nginx や PostgreSQL などのサービスのイメージでは、メインプロセスがフォアグラウンドで実行され続けるため、コンテナも動作し続けます。
作成と起動
docker run は実際には docker create(作成)と docker start(起動)を組み合わせたものです。それぞれを別々に実行することもできます。
$ docker create --name web nginx:1.30
ad99713ea5acddf70d854365e882fd0a3b6d4508d50da25993b94c9878f1c3bc
$ docker ps -a --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" Less than a second ago Created web
$ docker start web
web
$ docker ps --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" Less than a second ago Up Less than a second 80/tcp web
作成後の状態は Created、起動後は Up です。--filter name=web は、名前に web を含むコンテナだけを表示します。
名前は重複できません
docker run を実行するたびに、新しいコンテナが作成されます。コンテナ名がすでに使われている場合、そのコンテナが停止中でもエラーになります。
$ docker run -d --name web nginx:1.30
docker: Error response from daemon: Conflict. The container name "/web" is already in use by container "ad99713ea5acddf70d854365e882fd0a3b6d4508d50da25993b94c9878f1c3bc". You have to remove (or rename) that container to be able to reuse that name.
Run 'docker run --help' for more information
以前のコンテナをもう一度起動するには、docker start web を使います。新しい設定で作り直すには、先に docker rm -f web を実行してから docker run を実行します。
停止:stop と kill の違い
| コマンド | 動作 |
|---|---|
docker stop | まず SIGTERM を送り、プログラムが正常に終了処理できるようにします。10 秒経っても終了しない場合は、SIGKILL を送って強制終了します |
docker kill | SIGKILL を直接送り、すぐに終了させます |
stop を使うと、データベースがデータをディスクに書き戻したり、Web サーバーが処理中のリクエストを完了したりする時間をプログラムに与えられます。通常は stop を使い、プログラムが応答しなくなった場合にだけ kill を使います。
$ docker start web
web
$ docker kill web
web
$ docker ps -a --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" 14 seconds ago Exited (137) Less than a second ago web
kill されたコンテナの終了コードは 137 です(128 + 9。9 は SIGKILL の番号です)。
なぜ docker stop はときどき 10 秒待つのですか?
以下で、3 つのコンテナの停止にかかる時間を実際に比較します。
$ time docker stop web
web
real 0m 0.10s
user 0m 0.01s
sys 0m 0.00s
$ docker run -d --name slow alpine:3.23 sh -c "sleep 300"
Unable to find image 'alpine:3.23' locally
3.23: Pulling from library/alpine
d0c1d894c237: Pull complete
Digest: sha256:85fe1e81d6758c208f3e1eed4338a1997e19d4be002d4dd32d3100c9a8c010a0
Status: Downloaded newer image for alpine:3.23
170d08a64bb8ec1519d183f8c20508d669358eea4d5a978fa4f4675ffcec41ab
$ time docker stop slow
slow
real 0m 10.17s
user 0m 0.00s
sys 0m 0.01s
$ docker run -d --name slow2 --init alpine:3.23 sh -c "sleep 300"
d1854be4790b5fc9375004e05708d27a27d56c2c540a8159424351985db20ef9
$ time docker stop slow2
slow2
real 0m 0.13s
user 0m 0.00s
sys 0m 0.01s
| コンテナ | 停止時間 | 原因 |
|---|---|---|
| nginx | 0.10 秒 | nginx は SIGTERM を受け取ると、すぐに正常終了します |
sh -c "sleep 300" | 10.17 秒 | メインプロセスは sh です。PID 1 として実行されると SIGTERM を無視するため、Docker は 10 秒間待ってから SIGKILL で強制終了します |
同上、--init を追加 | 0.13 秒 | --init は小さな init プロセスを PID 1 として使い、シグナルを子プロセスに転送します |
Linux には PID 1 に関する特別なルールがあります。PID 1 が SIGTERM を自分で処理しない場合、このシグナルは無視されます。そのため、自作イメージで docker stop のたびに 10 秒待たされる場合、通常はメインプロセスが PID 1 として実行されており、プログラム内で SIGTERM を処理していません。たとえば、node server.js をメインプロセスとして直接実行する Node.js プログラムでも、実測では同じく 10 秒待つ必要があります。Dockerfile 命令リファレンスの実際の比較を参照してください。解決するには、プログラム内で SIGTERM を処理するか、--init を追加します。
終了コード
$ docker run --name exit3 alpine:3.23 sh -c "exit 3"
$ docker ps -a --filter name=exit3
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84996cca5ec5 alpine:3.23 "sh -c 'exit 3'" 1 second ago Exited (3) Less than a second ago exit3
$ docker inspect --format '{{.State.ExitCode}}' exit3
3
メインプロセスが終了したときのコードが、Exited (...) に表示されます。よくあるコードは次のとおりです。
| コード | よくある原因 |
|---|---|
0 | 正常終了 |
1 などのその他の数値 | プログラム自体が報告したエラーです。docker logs を確認してください |
137 | SIGKILL による終了です。docker kill、docker stop で長時間待った場合、またはメモリ不足でシステムに終了された場合(OOM)です |
143 | SIGTERM を受け取った後、正常終了しました(128 + 15) |
一時停止と再開
$ docker start web
web
$ docker pause web
web
$ docker ps --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" 15 seconds ago Up Less than a second (Paused) 80/tcp web
$ docker unpause web
web
pause はコンテナ内のすべてのプロセスを凍結します(終了はしません)。状態には (Paused) と表示されます。使う機会はあまりありませんが、メモリ内の状態を保ったまま、一時的に CPU を解放したい場合に適しています。
コンテナを削除する
$ docker rm web
Error response from daemon: cannot remove container "web": container is running: stop the container before removing or force remove
$ docker rm -f web
web
実行中のコンテナはそのまま削除できません。先に stop するか、-f で強制削除してください(kill の後に rm するのと同じです)。
停止済みのコンテナをまとめて削除する
しばらく練習すると、docker ps -a に停止済みのコンテナがたくさんたまります。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75ee00dc4081 nginx:1.30 "/docker-entrypoint.…" 1 second ago Up Less than a second 80/tcp web
5dfb843c0b40 alpine:3.23 "sh -c 'echo startin…" 26 seconds ago Exited (1) 24 seconds ago flaky
84996cca5ec5 alpine:3.23 "sh -c 'exit 3'" 27 seconds ago Exited (3) 26 seconds ago exit3
d1854be4790b alpine:3.23 "sh -c 'sleep 300'" 29 seconds ago Exited (143) 28 seconds ago slow2
170d08a64bb8 alpine:3.23 "sh -c 'sleep 300'" 39 seconds ago Exited (137) 29 seconds ago slow
66e6f85c66e0 ubuntu:26.04 "/bin/bash" 43 seconds ago Exited (0) 42 seconds ago dreamy_solomon
$ docker container prune -f
Deleted Containers:
5dfb843c0b400146827fe138890ee4d62a24104cad5531aff4100fc471b0727f
84996cca5ec5bfe7ca51c6365b60ef89e49055cf06a3f0dd3a49f9e50e08d6f4
d1854be4790b5fc9375004e05708d27a27d56c2c540a8159424351985db20ef9
170d08a64bb8ec1519d183f8c20508d669358eea4d5a978fa4f4675ffcec41ab
66e6f85c66e0f2b586c5919a900a0e16d6f0fc49535d35fa7d30f77747f1ce0e
Total reclaimed space: 24.58kB
container prune は停止済みのコンテナだけを削除するため、実行中の web には影響しません。また、上の終了コードと見比べてください。slow は強制終了されたため 137、--init を追加した slow2 は SIGTERM を正常に受け取ったため 143 です。
使い捨てのコンテナを終了後に自動削除するには、実行時に --rm を追加します。
docker run --rm alpine:3.23 echo "使い終わったら破棄"
再起動ポリシー:--restart
サーバーの再起動時やプログラムのクラッシュ時に、コンテナを自動的に再起動するかどうかを --restart で設定します。
| 値 | 動作 |
|---|---|
no | デフォルト値です。自動再起動しません |
on-failure[:回数] | 終了コードが 0 以外の場合にのみ再起動します。回数を制限できます |
always | 常に再起動します。手動で stop した後も、Docker 自体が再起動すると再び起動します |
unless-stopped | always と似ていますが、手動で stop した場合は自動起動しません |
on-failure の動作を確認する
次のコンテナは起動するたびに starting と出力してからコード 1 で終了し、繰り返しクラッシュするプログラムを再現します。
$ docker run -d --name flaky --restart on-failure:3 alpine:3.23 sh -c "echo starting; exit 1"
5dfb843c0b400146827fe138890ee4d62a24104cad5531aff4100fc471b0727f
$ docker ps -a --filter name=flaky
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5dfb843c0b40 alpine:3.23 "sh -c 'echo startin…" 25 seconds ago Exited (1) 23 seconds ago flaky
$ docker inspect --format '{{.RestartCount}} {{.State.Status}} {{.State.ExitCode}}' flaky
3 exited 1
$ docker logs flaky
starting
starting
starting
starting
ログには starting が 4 回あります。最初の起動に加えて 3 回再起動したためです(RestartCount は 3)。上限に達すると Exited (1) の状態で停止します。Docker は再起動のたびに待ち時間を徐々に長くし、ホストが頻繁な再起動でダウンしないようにします。
実行中のコンテナの再起動ポリシーを変更する
長期間稼働するサービスには、通常 unless-stopped をおすすめします。すでに実行中のコンテナも変更できます。
$ docker run -d --name web --restart unless-stopped nginx:1.30
75ee00dc4081f4c2849562fbd89edfdd9386839a161ea9d66956eaa41257d4cf
$ docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' web
unless-stopped
$ docker update --restart always web
web
$ docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' web
always
Linux でコンテナを起動時に自動起動するには、Docker 自体も起動時に自動起動する必要があります。
sudo systemctl enable dockerを実行してください。Docker Desktop では、設定で「Start Docker Desktop when you sign in」を有効にします。
コマンド一覧
| コマンド | 用途 |
|---|---|
docker run | 新しいコンテナを作成して起動 |
docker create | 作成のみ |
docker start / stop / restart | 既存のコンテナを起動 / 停止 / 再起動 |
docker kill | 強制終了(SIGKILL) |
docker pause / unpause | 一時停止 / 再開 |
docker rm [-f] | コンテナを削除 |
docker container prune | 停止中のコンテナをすべて削除 |
docker ps [-a] | コンテナを一覧表示(-a は停止中も含む) |
docker update --restart | 再起動ポリシーを変更 |
次のセクションでは、docker run のよく使うオプションを詳しくまとめます。
まとめ
- コンテナの状態:created、running、paused、exited、restarting。
- メインプロセスが終了するとコンテナも停止します。
docker stopはまず SIGTERM を送信し、10 秒後に SIGKILL を送信します。 - メインプロセスが PID 1 で SIGTERM を処理しない場合、stop は10秒間待機します。
--initで解決できます。 - 長期間稼働するサービスには
--restart unless-stoppedを指定します。
練習問題
練習 1:docker run -d --name t1 alpine:3.23 sh -c "exit 3" でコンテナを起動すると、状態と終了コードはどうなりますか?
解答
docker ps -a には Exited (3) と表示されます。docker inspect -f "{{.State.ExitCode}}" t1 でも終了コード 3 を取得できます。
練習 2:docker run -d --name t2 alpine:3.23 sleep 300 を起動し、time docker stop t2(先にコンテナを作り直してください)と --init を付けた場合で、停止にかかる時間を比べてください。
ヒント
--init を付けない場合、sleep は PID 1 で SIGTERM を無視するため、強制終了されるまで約10秒かかります。--init を付けると、init プロセスがシグナルを sleep に転送するため、ほぼすぐに停止します。
よくある質問
Exited (137) はどういう意味ですか?
137 = 128 + 9 で、コンテナが SIGKILL によって強制終了されたことを示します。docker kill、docker stop の待ち時間超過、メモリ不足によるシステムの終了などが原因です。
サーバーの再起動後、コンテナは自動的に起動しますか?
再起動ポリシー(例:--restart unless-stopped)を設定する必要があります。また、Docker 自体も起動時に自動起動するよう設定してください(Linux では sudo systemctl enable docker を実行します)。
一時停止(pause)と停止(stop)は何が違いますか?
pause はコンテナ内のすべてのプロセスを凍結し、メモリの内容を保持します。再開すると元の状態から続行します。stop はプロセスを終了するため、メモリ内の状態は失われます。
更新日 2026年10月14日