Docker: コンテナのライフサイクル管理
最終更新:2026-08-26
コンテナはプロセスと同様に完全なライフサイクルを持ちます。コンテナの状態遷移と運用コマンドを理解することは、Docker 運用の基礎スキルです。
1. 学べること
- コンテナの 6 つの状態とその遷移
- 開始/停止/再起動の操作
- 一時停止と再開の違い
- コンテナログの表示とフィルタリング
- コンテナプロセスとリソースのトラブルシューティング
2. 運用エンジニアの実話
(1) 問題点:本番コンテナが早朝にクラッシュ
Charlie の本番コンテナが午前 3 時に突然クラッシュしました。監視アラートが発報されましたが、Charlie はコンテナが終了した理由を知りませんでした — OOM エラー? アプリケーション例外? それとも手動で終了されたのか? コンテナを再構築せずに問題を迅速にトラブルシューティングする必要がありました。
(2) ログと監視のソリューション
docker logs が OOM エラーを表示し、docker stats がメモリオーバーフローことを確認しました。
BASH
# コンテナの終了ログを確認
docker logs --tail 50 myapp
# コンテナのリソース使用状況を確認
docker stats --no-stream
(3) メリット:5 分で根本原因を特定
Charlie は docker logs を使用して「Out of memory」エラーを検出し、docker inspect で終了コードが 137(OOM Kill)であることを確認し、--memory パラメータを調整した後、コンテナは正常に復帰しました。アラートから解決までわずか 5 分でした。
3. コンテナの 6 つの状態
作成から削除まで、コンテナは 6 つの状態を経ます。
stateDiagram-v2
[*] --> Created : docker create
Created --> Running : docker start
Created --> Running : docker run
Running --> Paused : docker pause
Paused --> Running : docker unpause
Running --> Stopped : docker stop / Ctrl+C
Running --> Stopped : docker kill
Stopped --> Running : docker start
Running --> Restarting : プロセスクラッシュ + 再起動ポリシー
Restarting --> Running : 再起動成功
Restarting --> Stopped : 再起動失敗
Running --> Dead : 回復不能エラー
Stopped --> [*] : docker rm
Dead --> [*] : docker rm
(1) 状態の詳細説明
| ステータス | 説明 | 一般的なトリガー |
|---|---|---|
| Created | 作成されたが起動していない | docker create / docker run(まだ起動していない) |
| Running | 実行中 | docker start / docker run -d |
| Paused | 一時停止中(プロセスが凍結) | docker pause |
| Stopped | 停止中(Exited) | docker stop / docker kill / プロセス終了 |
| Restarting | 再起動中 | コンテナクラッシュ + 再起動ポリシーがトリガー |
| Dead | 回復不能 | Docker 内部エラー(極めて稀) |
(2) コンテナステータスの表示
BASH
# 実行中のコンテナを一覧表示(Running 状態のみ)
docker ps
# すべてのコンテナを一覧表示(すべての状態)
docker ps -a
# ステータスでフィルタ
docker ps -a --filter "status=exited"
docker ps -a --filter "status=running"
4. 開始、停止、再起動
▶ サンプル:start / stop / restart(難易度 ⭐)
BASH
# コンテナを作成して起動
docker run -d --name web -p 8080:80 nginx:latest
# コンテナを停止(グレースフルシャットダウン)
docker stop web
# 再度起動
docker start web
# 再起動(stop + start を 1 コマンドで)
docker restart web
# 各操作後にステータスを確認
docker ps -a --filter name=web
(1) docker stop vs docker kill
| 観点 | docker stop |
docker kill |
|---|---|---|
| シグナル | SIGTERM → 猶予期間 → SIGKILL | SIGKILL(デフォルト) |
| エレガント | ✅ アプリに 30 秒のクリーンアップ時間を与える | ❌ 即座に強制終了 |
| データセキュリティ | アプリはデータを書き込み接続を閉じることができる | 書き込まれていないデータは失われる可能性 |
| 待機時間 | デフォルト 30 秒(-t で調整可能) |
待機なし |
| ユースケース | 通常のシャットダウン | コンテナが応答しないときの強制終了 |
BASH
# カスタムタイムアウト(60 秒)でグレースフル停止
docker stop -t 60 web
# 即座に強制 kill
docker kill web
# カスタムシグナルを送信
docker kill -s SIGUSR1 web
💡 ヒント: 本番環境ではデフォルトで
docker stop を使用し、コンテナが応答しない場合にのみ docker kill を使用してください。アプリケーションは SIGTERM シグナルを適切に処理してグレースフルシャットダウンを保証する必要があります。
5. 一時停止と再開
▶ サンプル:pause / unpause(難易度 ⭐⭐)
BASH
# コンテナを一時停止(すべてのプロセスを凍結)
docker pause web
# 確認:ステータスが「Paused」になっているはず
docker ps -a --filter name=web
# コンテナの一時停止を解除
docker unpause web
(1) docker pause vs docker stop
| 観点 | docker pause |
docker stop |
|---|---|---|
| メカニズム | プロセス凍結(cgroup freeze) | SIGTERM シグナルを送信 |
| メモリ | メモリ内に保持 | メモリが解放される |
| 復旧速度 | 即座(解凍) | プロセスの再起動が必要 |
| ポート使用中 | まだ使用中 | 解放済み |
| ユースケース | CPU リソースを一時的に解放、デバッグ | サービスを正常にシャットダウン |
⚠️ 注意: 一時停止中のコンテナはメモリとポートを消費し続けるため、長時間一時停止したままにしないでください。リソースを解放する必要がある場合は
docker stop を使用してください。
6. コンテナログの表示
▶ サンプル:リアルタイムコンテナログ監視(難易度 ⭐⭐)
BASH
# リアルタイムでログを追跡
docker logs -f web
# 最後の 100 行を表示
docker logs --tail 100 web
# 過去 2 時間からのログを表示
docker logs --since 2h web
# 特定の期間内のログを表示
docker logs --since "2024-01-15T10:00:00" --until "2024-01-15T12:00:00" web
💻 出力:
TEXT
📖 参照専用
10.0.0.1 - - [15/Jan/2024:10:05:22 +0000] "GET / HTTP/1.1" 200 615
10.0.0.1 - - [15/Jan/2024:10:05:23 +0000] "GET /favicon.ico HTTP/1.1" 404 555
(1) ログパラメータのクイックリファレンス
| パラメータ | 機能 | 例 |
|---|---|---|
-f / --follow |
リアルタイム追跡 | docker logs -f web |
--tail N |
最後の N 行を表示 | --tail 100 |
--since |
特定の時刻以降のログを表示 | --since 2h / --since "2024-01-15" |
--until |
特定の時刻までのログを表示 | --until 30m |
-t / --timestamps |
タイムスタンプを表示 | docker logs -t web |
7. コンテナリソース監視とトラブルシューティング
▶ サンプル:コンテナリソースのリアルタイム監視(難易度 ⭐⭐)
BASH
# すべてのコンテナのリソース統計をリアルタイム表示
docker stats
# 一回限りのスナップショット(ストリーミングなし)
docker stats --no-stream
# 特定のコンテナのみの統計
docker stats web --no-stream
💻 出力:
TEXT
📖 参照専用
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1b2c3d4e5f6 web 0.02% 4.2MiB / 512MiB 0.82% 1.2kB / 0B 0B / 0B 9
▶ サンプル:コンテナ内のプロセスの表示(難易度 ⭐)
BASH
# コンテナ内で実行中のプロセスを一覧表示
docker top web
💻 出力:
TEXT
📖 参照専用
UID PID PPID C STIME TTY TIME CMD
root 1234 5678 0 10:05 ? 00:00:00 nginx: master process
www 1235 1234 0 10:05 ? 00:00:00 nginx: worker process
▶ サンプル:コンテナ設定詳細の表示(難易度 ⭐⭐)
BASH
# 完全なコンテナ設定(JSON)
docker inspect web
# 特定のフィールドを抽出
docker inspect web --format='{{.State.Status}}'
docker inspect web --format='{{.State.ExitCode}}'
docker inspect web --format='{{.NetworkSettings.IPAddress}}'
docker inspect web --format='{{.HostConfig.Memory}}'
💻 出力:
TEXT
📖 参照専用
running
0
172.17.0.2
536870912
8. 実行中コンテナへのアクセス
▶ サンプル:docker exec を使用してコンテナに入る(難易度 ⭐⭐)
BASH
# 実行中コンテナの内部でインタラクティブシェルを開く
docker exec -it web bash
# コンテナ内で単一コマンドを実行
docker exec web cat /etc/nginx/nginx.conf
# コンテナからホストにファイルをコピー
docker cp web:/etc/nginx/nginx.conf ./nginx.conf
💡 ヒント:
docker exec は新しいコンテナを作成しません。代わりに、実行中のコンテナ内で新しいプロセスを開始します。これはデバッグと一時的な操作に適しています。本番環境では docker exec への依存を避け、代わりにボリュームマウントとログ収集を使用してください。
9. 完全な例:コンテナトラブルシューティングのシミュレーション
BASH
# ============================================
# 完全なチュートリアル:コンテナクラッシュ診断
# 範囲:run、crash、logs、inspect、fix、restart
# ============================================
# 1. メモリ制限のあるコンテナを起動
docker run -d \
--name crash-test \
--memory=50m \
--restart=on-failure:3 \
nginx:latest
# 2. 実行中であることを確認
docker ps --filter name=crash-test
# 3. コンテナ内からメモリ負荷をシミュレート
docker exec -it crash-test bash -c "dd if=/dev/zero of=/tmp/bigfile bs=1M count=100"
# 4. コンテナが OOM kill された可能性があるため、ステータスを確認
docker ps -a --filter name=crash-test
# 5. 終了コードを確認(137 = OOM Kill)
docker inspect crash-test --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'
# 6. クラッシュ理由のログを確認
docker logs --tail 20 crash-test
# 7. Docker イベントで OOM を確認
docker events --filter event=oom --since 5m
# 8. 修正:メモリ制限を増加(再作成が必要)
docker stop crash-test
docker rm crash-test
docker run -d \
--name crash-test \
--memory=256m \
--restart=on-failure:3 \
nginx:latest
# 9. 修正を検証
docker ps --filter name=crash-test
docker stats crash-test --no-stream
💻 出力(抜粋):
TEXT
📖 参照専用
# docker inspect --format
ExitCode: 137, OOMKilled: true
# docker events
2024-01-15T10:05:22Z container oom crash-test...
# 修正後
CONTAINER ID IMAGE STATUS NAMES
b2c3d4e5f6a7 nginx:latest Up 10 seconds crash-test
❓ よくある質問
Q コンテナ停止後もデータは残っていますか?
A はい。コンテナの停止は単にプロセスを一時停止するだけで、ファイルシステムはディスク上に残ります。
docker start で復元できます。ただし、docker rm でコンテナを削除した後はデータが消えます — ボリュームがマウントされていない限り。Q
docker stop と docker kill の違いは何ですか?A
stop は SIGTERM シグナルを送信し、アプリケーションに 30 秒間のグレースフルシャットダウン(書き込み完了と接続クローズ)を与えます。タイムアウトした場合、SIGKILL シグナルを送信します。kill は即座に SIGKILL シグナルを送信してプロセスを終了します。本番環境では可能な限り stop を使用し、コンテナが応答しない場合にのみ kill を使用してください。Q コンテナがクラッシュした後に自動再起動するように設定するには?
A コンテナ起動時に
--restart=always または --restart=unless-stopped を追加します。「always」は終了理由に関係なくコンテナを再起動します。「unless-stopped」は手動停止後の自動再起動を防ぎます。本番の Web サービスには unless-stopped を推奨します。Q コンテナログファイルが大きすぎる場合はどうすればよいですか?
A Docker のデフォルトのログドライバー
json-file は自動的にログをローテーションしないため、ログが無制限に増加する可能性があります。起動時にログ制限を設定します: docker run --log-opt max-size=10m --log-opt max-file=3。これにより各ログファイルが 10 MB に制限され、最大 3 ファイルが保持されます。Q 実行中のコンテナに入るには?
A
docker exec -it <container> bash(または sh)。これは最も一般的なデバッグ方法です。コンテナに bash がない場合は docker exec -it <container> sh を使用してください。docker attach を使用して接続することもできますが、メインプロセスの stdin に接続し、Ctrl+C を押すとコンテナが停止するため、一般的には使用されません。Q 終了コード 137 は何を意味しますか?
A 137 = 128 + 9、ここで 9 は SIGKILL のシグナル番号です。コンテナが OOM Killer によって強制終了された場合、終了コードは 137 です。他の一般的な終了コード:0 = 正常終了、1 = アプリケーションエラー、2 = コマンド誤用、125 = Docker デーモンエラー。
📖 まとめ
- コンテナには 6 つの状態がある:Created / Running / Paused / Stopped / Restarting / Dead
docker stopグレースフルシャットダウン(SIGTERM)、docker kill強制終了(SIGKILL)docker pauseプロセスを凍結してメモリを保持。docker stopメモリを解放docker logsは-fリアルタイム追跡、--since/--until時間フィルタ、--tail行制限をサポートdocker statsリソース監視、docker topプロセス表示、docker inspect設定表示- 終了コード 137 = OOM Kill、コンテナ問題のトラブルシューティングの重要な手がかり
📝 練習問題
- 基本練習 (難易度 ⭐): Nginx コンテナを起動した後、
docker stopを使用して停止し、docker startを使用して再起動し、各操作後にdocker ps -aで表示されるステータス変化を記録してください。 - 応用練習 (難易度 ⭐⭐):
docker logs --tail 50 -fを使用して Nginx コンテナログをリアルタイムで表示してください。ブラウザでhttp://localhost:8080を 10 回訪問し、ログ内のリクエストエントリを観察してください。 - チャレンジ (難易度: ⭐⭐⭐):
docker exec -itを使用して Nginx コンテナにアクセスし、/usr/share/nginx/html/index.htmlの内容を変更し、ブラウザでページを訪問して変更が有効になったことを確認してください。考えてみてください:コンテナが削除された後、変更は保持されますか? 変更を永続的にするにはどうすればよいですか?
前のレッスン: Docker イメージ管理
次のレッスン: ミニプロジェクト — LEMP スタックのコンテナ化