Docker: コンテナのライフサイクル管理

最終更新:2026-08-26

コンテナはプロセスと同様に完全なライフサイクルを持ちます。コンテナの状態遷移と運用コマンドを理解することは、Docker 運用の基礎スキルです。

1. 学べること


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 つの状態を経ます。

100%
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 stopdocker 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 デーモンエラー。

📖 まとめ


📝 練習問題

  1. 基本練習 (難易度 ⭐): Nginx コンテナを起動した後、docker stop を使用して停止し、docker start を使用して再起動し、各操作後に docker ps -a で表示されるステータス変化を記録してください。
  2. 応用練習 (難易度 ⭐⭐): docker logs --tail 50 -f を使用して Nginx コンテナログをリアルタイムで表示してください。ブラウザで http://localhost:8080 を 10 回訪問し、ログ内のリクエストエントリを観察してください。
  3. チャレンジ (難易度: ⭐⭐⭐): docker exec -it を使用して Nginx コンテナにアクセスし、/usr/share/nginx/html/index.html の内容を変更し、ブラウザでページを訪問して変更が有効になったことを確認してください。考えてみてください:コンテナが削除された後、変更は保持されますか? 変更を永続的にするにはどうすればよいですか?
前のレッスン: Docker イメージ管理 次のレッスン: ミニプロジェクト — LEMP スタックのコンテナ化
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%