STEP 9:ログとデバッグ手法

🐳 STEP 9: ログとデバッグ手法

docker logsを使いこなし、コンテナのトラブルシューティングをマスターする

📋 このステップで学ぶこと

  • docker logsコマンドの基本と各オプション
  • リアルタイムログ監視(-f オプション)
  • 時間範囲やログ行数の指定方法
  • ログのフィルタリングと分析テクニック
  • ログドライバーとログローテーションの設定
  • コンテナのデバッグフローとトラブルシューティング
  • よくあるエラーとその解決方法

📝 1. docker logsの基本

1-1. ログとは何か

ログとは、アプリケーションが出力するメッセージの記録です。
いつ何が起こったかを記録しており、トラブルシューティングの重要な情報源です。

📚 日記で例えると…

アプリケーションが書く「日記」のようなものです。

「10:00 サーバー起動完了」
「10:05 ユーザーAがログイン」
「10:15 データベース接続エラー発生」
「10:20 エラー解消、正常稼働」

この記録を見ることで、何がいつ起こったかを把握できます。

1-2. Dockerのログの仕組み

Dockerコンテナは、アプリケーションの出力を標準出力(stdout)標準エラー出力(stderr)から収集します。

【Dockerのログ収集の仕組み】 ┌────────────────────────────────────────┐ │ コンテナ内のアプリケーション │ │ │ │ print(“情報メッセージ”) ──────▶ stdout │ │ print(“エラー!”, file=stderr) ▶ stderr │ └────────────────────────────────────────┘ │ │ └──────┬───────┘ ▼ Docker Engine が収集 │ ▼ JSON形式でファイルに保存 /var/lib/docker/containers/ <container-id>/<container-id>-json.log │ ▼ docker logs コマンドで表示
💡 ログは標準出力に

Dockerのベストプラクティスは、ログをファイルではなく標準出力に出力することです。
そうすることで、docker logsで簡単に確認でき、
ログ収集システムとの連携も容易になります。

1-3. docker logsの基本コマンド

docker logs my-nginx
📝 コマンドの意味
  • docker logs :コンテナのログを表示するコマンド
  • my-nginx :ログを表示するコンテナ名(またはコンテナID)
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 2024/01/15 10:30:45 [notice] 1#1: using the “epoll” event method 2024/01/15 10:30:45 [notice] 1#1: nginx/1.25.3 2024/01/15 10:30:45 [notice] 1#1: start worker processes 172.17.0.1 – – [15/Jan/2024:10:31:00 +0000] “GET / HTTP/1.1” 200 615 “-” “curl/7.81.0”

1-4. ログの種類

出力先 説明
stdout(標準出力) 通常のメッセージ。情報ログ、アクセスログなど。
stderr(標準エラー出力) エラーメッセージ、警告など。

docker logsは、stdout と stderr の両方をまとめて表示します。

⚙️ 2. docker logsのオプション

2-1. オプション一覧

オプション 説明
-f, --follow リアルタイムでログを表示し続ける。新しいログが出力されるたびに表示される。Ctrl+Cで終了。
--tail N 最新のN行だけを表示。例:--tail 100で最新100行のみ。
-t, --timestamps 各行にタイムスタンプを付けて表示。いつのログか明確になる。
--since 指定した時刻以降のログを表示。--since 1h(1時間前から)や--since "2024-01-15T10:00:00"
--until 指定した時刻までのログを表示。--sinceと組み合わせて時間範囲を指定。
-n N --tail Nと同じ。最新N行を表示。
--details 追加の属性(環境変数など)を表示。

2-2. リアルタイムログ監視(-f)

開発中に最もよく使うオプションが-f(follow)です。

docker logs -f my-nginx
📝 コマンドの意味
  • -f :follow(追従)モード。新しいログが出力されると自動的に表示される
  • Linuxのtail -fコマンドと同じ動作
  • Ctrl+Cで終了
# 最新100行からリアルタイム監視を開始 docker logs -f –tail 100 my-nginx

2-3. ログ行数の指定(–tail)

# 最新10行だけ表示 docker logs –tail 10 my-nginx
📝 コマンドの意味
  • --tail 10 :最新10行だけを表示
  • ログが大量にある場合に、必要な分だけ確認できる
# 最新50行を表示 docker logs –tail 50 my-nginx # 全てのログを表示(デフォルト) docker logs my-nginx

2-4. タイムスタンプ付き表示(-t)

docker logs -t my-nginx
📝 コマンドの意味
  • -t :各行の先頭にDockerが付与したタイムスタンプを表示
  • アプリケーション自体がタイムスタンプを出力しない場合に便利
2024-01-15T10:30:45.123456789Z /docker-entrypoint.sh: Configuration complete 2024-01-15T10:31:00.987654321Z 172.17.0.1 – – [15/Jan/2024:10:31:00 +0000] “GET / HTTP/1.1” 200 615

2-5. 時間範囲の指定(–since / –until)

# 過去1時間のログ docker logs –since 1h my-nginx
📝 コマンドの意味
  • --since 1h :1時間前から現在までのログを表示
  • 相対時間(1h, 30m, 2d など)と絶対時間の両方が使える
# 過去30分のログ docker logs –since 30m my-nginx # 過去2日間のログ docker logs –since 2d my-nginx # 特定の日時以降 docker logs –since “2024-01-15T10:00:00” my-nginx # 特定の時間範囲(10:00〜12:00) docker logs –since “2024-01-15T10:00:00” –until “2024-01-15T12:00:00” my-nginx

2-6. オプションの組み合わせ

複数のオプションを組み合わせて、より細かくログを確認できます。

# 最新100行をタイムスタンプ付きでリアルタイム監視 docker logs -f -t –tail 100 my-nginx # 過去1時間の最新50行をタイムスタンプ付きで表示 docker logs -t –tail 50 –since 1h my-nginx

🔍 3. ログのフィルタリングと分析

3-1. ログをファイルに保存

シェルのリダイレクト機能を使って、ログをファイルに保存できます。

# ログをファイルに保存(stdout と stderr 両方) docker logs my-nginx > nginx.log 2>&1
📝 コマンドの意味
  • > :標準出力をファイルにリダイレクト
  • 2>&1 :標準エラー出力(2)を標準出力(1)と同じ先に送る
  • 結果として、stdout と stderr の両方が nginx.log に保存される
# 標準出力と標準エラーを別々に保存 docker logs my-nginx > nginx_stdout.log 2> nginx_stderr.log # 追記モード(既存ファイルに追加) docker logs my-nginx >> nginx.log 2>&1

3-2. grepでログを絞り込み

grepコマンドと組み合わせて、特定のパターンを含むログだけを表示できます。

# エラーメッセージだけ表示 docker logs my-nginx 2>&1 | grep -i error
📝 コマンドの意味
  • 2>&1 :stderr も stdout に含める(grepに渡すため)
  • | :パイプ。前のコマンドの出力を次のコマンドに渡す
  • grep -i error :「error」を含む行を抽出(-iは大文字小文字を区別しない)
# 特定のIPアドレスのアクセス docker logs my-nginx | grep “192.168.1.100” # HTTPステータスコード404(Not Found)のログ docker logs my-nginx | grep ‘” 404 ‘ # 複数のキーワードで絞り込み(OR検索) docker logs my-nginx 2>&1 | grep -E “error|warning|critical” # 特定のキーワードを除外 docker logs my-nginx | grep -v “健康チェック”

3-3. ログの統計情報を取得

# エラー数をカウント docker logs my-nginx 2>&1 | grep -i error | wc -l
📝 コマンドの意味
  • wc -l :行数をカウント(word count の line)
# GETリクエストの数 docker logs my-nginx | grep “GET” | wc -l # POSTリクエストの数 docker logs my-nginx | grep “POST” | wc -l # IPアドレスごとのアクセス数(多い順) docker logs my-nginx | awk ‘{print $1}’ | sort | uniq -c | sort -rn | head -10 # HTTPステータスコード別の集計 docker logs my-nginx | awk ‘{print $9}’ | sort | uniq -c | sort -rn

3-4. リアルタイムでフィルタリング

# エラーログをリアルタイム監視 docker logs -f my-nginx 2>&1 | grep -i error # 特定のパスへのアクセスを監視 docker logs -f my-nginx | grep “/api/” # エラーをハイライト表示(全ログを表示しつつ) docker logs -f my-nginx | grep –color=always -E “error|$”

3-5. 便利なエイリアスの設定

よく使うコマンドはエイリアス(短縮名)を設定しておくと便利です。

# ~/.bashrc または ~/.zshrc に追加 alias dlog=’docker logs’ alias dlogf=’docker logs -f’ alias dlogt=’docker logs -f –tail 100′ alias dlogerr=’docker logs 2>&1 | grep -i error’
# 使用例 dlog my-nginx # ログ表示 dlogf my-nginx # リアルタイム監視 dlogt my-nginx # 最新100行からリアルタイム監視 dlogerr my-nginx # エラーのみ表示

📊 4. ログドライバーとログローテーション

4-1. ログドライバーとは

Dockerはログドライバーを使って、ログの保存方法を制御します。
デフォルトはjson-fileドライバーで、JSONファイルとして保存されます。

ドライバー 説明
json-file デフォルト。ログをJSONファイルに保存。docker logsで確認可能。
local 最適化されたローカルファイル形式。json-fileより効率的。
syslog syslogデーモンに送信。中央ログサーバーへの転送に使用。
journald systemdのjournaldに送信。
fluentd Fluentdに送信。ログ収集・転送システムとの連携。
awslogs Amazon CloudWatch Logsに送信。
none ログを保存しない。docker logsは使用不可。

4-2. ログローテーションの設定

ログファイルが大きくなりすぎないように、ローテーション(ログファイルの分割・削除)を設定します。

# ログローテーション付きでコンテナを起動 docker run -d –name my-nginx \ –log-driver json-file \ –log-opt max-size=10m \ –log-opt max-file=3 \ -p 8080:80 nginx
📝 オプションの意味
  • --log-driver json-file :ログドライバーを指定(デフォルト)
  • --log-opt max-size=10m :1ファイル最大10MB
  • --log-opt max-file=3 :最大3ファイルまで保持(古いものは削除)
  • この設定では、最大30MB(10MB × 3ファイル)のログを保持

4-3. デフォルトのログ設定を変更

全コンテナに適用するデフォルト設定は、/etc/docker/daemon.jsonで指定します。

【/etc/docker/daemon.json の設定例】 { “log-driver”: “json-file”, “log-opts”: { “max-size”: “10m”, “max-file”: “3” } }
# 設定を反映するためにDockerを再起動 sudo systemctl restart docker
⚠️ ログ肥大化の危険性

ログローテーションを設定しないと、ディスク容量を使い切る危険があります。
特に本番環境では、必ずログローテーションを設定しましょう。

現在のログファイルサイズを確認するコマンド:

# コンテナのログファイルパスを取得 docker inspect –format='{{.LogPath}}’ my-nginx # ログファイルのサイズを確認 ls -lh $(docker inspect –format='{{.LogPath}}’ my-nginx)

4-4. ログを無効化する

# ログを保存しない(docker logsは使用不可になる) docker run -d –name my-nginx \ –log-driver none \ nginx
⚠️ 本番環境での使用は非推奨

--log-driver noneを使うと、トラブル時にログが確認できません。
開発時のテスト用途など、限定的な場面でのみ使用してください。

🐛 5. コンテナのデバッグ方法

5-1. デバッグの基本フロー

コンテナに問題が発生した場合の、基本的なデバッグフローです。

【トラブルシューティングの流れ】 Step 1: コンテナの状態を確認 └─▶ docker ps -a Step 2: ログを確認 └─▶ docker logs コンテナ名 Step 3: 詳細情報を確認 └─▶ docker inspect コンテナ名 Step 4: コンテナ内に入って調査 └─▶ docker exec -it コンテナ名 bash Step 5: リソース使用状況を確認 └─▶ docker stats コンテナ名 Step 6: イベント履歴を確認 └─▶ docker events

5-2. よくあるトラブルと対処法

❌ トラブル1:コンテナがすぐに停止する
# 1. 状態を確認 docker ps -a # STATUS: Exited (1) 10 seconds ago # 2. 終了コードを確認 docker inspect –format='{{.State.ExitCode}}’ my-container # 0 = 正常終了、1以上 = 異常終了 # 3. ログでエラー原因を確認 docker logs my-container # 4. 最後の数行を確認 docker logs –tail 50 my-container

よくある原因:
・起動コマンドが間違っている
・必要なファイルや設定がない
・環境変数が設定されていない
・依存サービスに接続できない

❌ トラブル2:コンテナに接続できない
# 1. コンテナが起動しているか確認 docker ps # 2. ポートマッピングを確認 docker port my-container # 80/tcp -> 0.0.0.0:8080 # 3. コンテナのIPアドレスを確認 docker inspect -f ‘{{.NetworkSettings.IPAddress}}’ my-container # 4. コンテナ内からテスト docker exec my-container curl localhost:80 # 5. ホストからテスト curl http://localhost:8080

よくある原因:
・ポートマッピングの設定ミス
・アプリケーションがlocalhost(127.0.0.1)のみにバインド
・ファイアウォールでブロック
・コンテナ内のサービスが起動していない

❌ トラブル3:パフォーマンスが悪い
# 1. リソース使用状況を確認 docker stats my-container # 2. メモリ制限を確認 docker inspect –format='{{.HostConfig.Memory}}’ my-container # 0 = 無制限 # 3. CPU制限を確認 docker inspect –format='{{.HostConfig.CpuPeriod}} {{.HostConfig.CpuQuota}}’ my-container # 4. コンテナ内のプロセスを確認 docker top my-container # 5. ディスクI/Oを確認 docker stats –format “{{.Name}}: {{.BlockIO}}”

よくある原因:
・メモリ不足
・CPU競合
・ディスクI/Oのボトルネック
・ログファイルの肥大化

5-3. docker eventsでイベントを監視

docker eventsは、Dockerデーモンのイベントをリアルタイムで表示します。

docker events
📝 コマンドの意味

docker events :コンテナの起動、停止、削除などのイベントをリアルタイム表示
コンテナが予期せず停止した場合など、何が起こったかを確認できます。

2024-01-15T10:30:45.123456789+09:00 container start abc123def456 (image=nginx, name=my-nginx) 2024-01-15T10:35:20.987654321+09:00 container die abc123def456 (exitCode=0, image=nginx, name=my-nginx) 2024-01-15T10:35:21.123456789+09:00 container stop abc123def456 (image=nginx, name=my-nginx)
# 特定のコンテナのイベントのみ docker events –filter container=my-nginx # 特定のイベントタイプのみ docker events –filter event=die # 過去1時間のイベント docker events –since 1h

🔧 6. 高度なデバッグテクニック

6-1. コンテナ内でデバッグツールを使う

# コンテナ内に入る docker exec -it my-nginx bash # プロセス一覧 ps aux # ネットワーク接続を確認 netstat -tulpn # または ss -tulpn # ディスク使用量 df -h # ファイルを探す find / -name “*.log” 2>/dev/null # 設定ファイルを確認 cat /etc/nginx/nginx.conf # ログファイルをリアルタイム監視 tail -f /var/log/nginx/error.log

6-2. コンテナにツールがない場合

軽量イメージには必要なツールがインストールされていないことがあります。

# Debian/Ubuntu系のコンテナ docker exec -it my-container bash apt-get update apt-get install -y curl wget vim net-tools procps # Alpine系のコンテナ docker exec -it my-container sh apk add –no-cache curl wget vim busybox-extras
⚠️ 一時的なインストール

コンテナ内でインストールしたツールは、コンテナを再起動すると消えます。
永続的に使いたい場合は、Dockerfileに追加する必要があります。

6-3. 別のコンテナからネットワークデバッグ

デバッグ用のコンテナを使って、ネットワークを調査することもできます。

# nicolakaという人が作成したnetshootというデバッグ用イメージ docker run -it –rm –network container:my-nginx nicolaka/netshoot # 同じネットワーク名前空間で様々なツールが使える ping localhost curl localhost ss -tulpn tcpdump -i any port 80

6-4. 停止したコンテナのデバッグ

docker execは実行中のコンテナでしか使えませんが、停止したコンテナからイメージを作成してデバッグする方法があります。

# 停止したコンテナからイメージを作成 docker commit my-stopped-container debug-image # そのイメージからシェルを起動 docker run -it –rm debug-image bash # 調査後、イメージを削除 docker rmi debug-image

💪 7. 練習問題

練習問題 1 基礎

Nginxのアクセスログをリアルタイムで監視してください

Nginxコンテナを起動し、ログをリアルタイムで表示しながら、ブラウザからアクセスしてログが表示されることを確認してください。

【解答】
# 1. Nginxコンテナを起動 docker run -d –name my-nginx -p 8080:80 nginx # 2. ログをリアルタイム表示 docker logs -f my-nginx # 3. 別のターミナルまたはブラウザでアクセス curl http://localhost:8080 # 4. ログにアクセス記録が表示される # 172.17.0.1 – – [15/Jan/2024:10:31:00 +0000] “GET / HTTP/1.1” 200 615 # Ctrl+C でログ監視を終了 # 後片付け docker rm -f my-nginx
練習問題 2 基礎

最新10行のログをタイムスタンプ付きで表示してください

Nginxコンテナの最新10行のログを、タイムスタンプ付きで表示してください。

【解答】
# コンテナを起動(まだない場合) docker run -d –name my-nginx -p 8080:80 nginx # 何度かアクセスしてログを生成 curl http://localhost:8080 curl http://localhost:8080 curl http://localhost:8080 # 最新10行をタイムスタンプ付きで表示 docker logs -t –tail 10 my-nginx # 後片付け docker rm -f my-nginx
練習問題 3 基礎

ログをファイルに保存してください

Nginxコンテナのログを nginx.log ファイルに保存してください。

【解答】
# コンテナを起動 docker run -d –name my-nginx -p 8080:80 nginx # アクセスしてログを生成 curl http://localhost:8080 # ログをファイルに保存 docker logs my-nginx > nginx.log 2>&1 # 保存されたことを確認 cat nginx.log # 後片付け docker rm -f my-nginx rm nginx.log
練習問題 4 応用

エラーログだけを抽出してください

タスク:

  1. Nginxコンテナを起動
  2. 存在しないページにアクセスして404エラーを発生させる
  3. grepを使って404エラーのログだけを表示
【解答】
# 1. コンテナを起動 docker run -d –name my-nginx -p 8080:80 nginx # 2. 正常なアクセス curl http://localhost:8080 # 存在しないページにアクセス(404エラー) curl http://localhost:8080/not-exist curl http://localhost:8080/another-missing-page # 3. 404エラーだけを表示 docker logs my-nginx | grep ‘” 404 ‘ # エラー数をカウント docker logs my-nginx | grep ‘” 404 ‘ | wc -l # 後片付け docker rm -f my-nginx
練習問題 5 応用

ログローテーション付きでコンテナを起動してください

最大ファイルサイズ5MB、最大3ファイルのログローテーション設定でNginxコンテナを起動してください。

【解答】
# ログローテーション付きで起動 docker run -d –name my-nginx \ –log-driver json-file \ –log-opt max-size=5m \ –log-opt max-file=3 \ -p 8080:80 nginx # 設定を確認 docker inspect –format='{{.HostConfig.LogConfig}}’ my-nginx # ログファイルのパスを確認 docker inspect –format='{{.LogPath}}’ my-nginx # 後片付け docker rm -f my-nginx
練習問題 6 応用

コンテナが停止する原因を調査してください

タスク:

  1. わざと失敗するコンテナを起動(存在しないコマンドを指定)
  2. docker ps -a で状態を確認
  3. 終了コードとログを確認して原因を特定
【解答】
# 1. 存在しないコマンドで起動(失敗する) docker run -d –name fail-test nginx nonexistent-command # 2. 状態を確認 docker ps -a | grep fail-test # STATUS: Exited (127) X seconds ago # 127 = コマンドが見つからない # 3. 終了コードを確認 docker inspect –format='{{.State.ExitCode}}’ fail-test # 4. ログを確認 docker logs fail-test # Error: nonexistent-command: No such file or directory # 後片付け docker rm fail-test
練習問題 7 発展

docker eventsでコンテナのライフサイクルを監視してください

タスク:

  1. ターミナルAで docker events を起動
  2. ターミナルBでコンテナを起動・停止・削除
  3. ターミナルAでイベントが表示されることを確認
【解答】
# ターミナルA:イベント監視を開始 docker events # ターミナルB:コンテナ操作 docker run -d –name event-test nginx docker stop event-test docker rm event-test # ターミナルAに以下のようなイベントが表示される: # container create abc123… (image=nginx, name=event-test) # container start abc123… # container die abc123… (exitCode=0) # container stop abc123… # container destroy abc123… # Ctrl+C でイベント監視を終了
練習問題 8 発展

アクセスログの統計情報を取得してください

タスク:

  1. Nginxコンテナを起動
  2. 複数回アクセス(正常ページ、存在しないページ)
  3. HTTPステータスコード別のアクセス数を集計
【解答】
# 1. コンテナを起動 docker run -d –name my-nginx -p 8080:80 nginx # 2. 様々なアクセスを生成 curl http://localhost:8080 # 200 curl http://localhost:8080 # 200 curl http://localhost:8080 # 200 curl http://localhost:8080/notfound # 404 curl http://localhost:8080/missing # 404 # 3. ステータスコード別の集計 # Nginxのログ形式: IP – – [日時] “リクエスト” ステータスコード サイズ … docker logs my-nginx | awk ‘{print $9}’ | sort | uniq -c | sort -rn # 出力例: # 3 200 # 2 404 # 総アクセス数 docker logs my-nginx | grep -c “GET” # 後片付け docker rm -f my-nginx

📝 STEP 9 のまとめ

✅ このステップで学んだこと
  • docker logsでコンテナのログを確認
  • -fオプションでリアルタイム監視
  • –tail Nで最新N行だけ表示
  • –since / –untilで時間範囲を指定
  • grepと組み合わせてログをフィルタリング
  • ログドライバーログローテーションの設定
  • トラブルシューティングの基本フロー
  • docker eventsでイベントを監視
📊 今回学んだコマンド一覧
コマンド 機能
docker logs コンテナ ログを表示
docker logs -f コンテナ リアルタイムでログを監視
docker logs --tail N 最新N行だけ表示
docker logs -t タイムスタンプ付きで表示
docker logs --since 1h 過去1時間のログを表示
docker events Dockerイベントをリアルタイム表示
💡 重要ポイント

ログはトラブルシューティングの第一歩です。
問題が起きたら、まずdocker logsで確認しましょう。

開発中はdocker logs -fでリアルタイム監視をしながら作業すると、
問題を素早く発見できます。

本番環境では必ずログローテーションを設定して、
ディスク容量を圧迫しないようにしましょう。

🎯 次のステップの予告

次のSTEP 10では、「ボリュームとデータ永続化」を学びます。

  • コンテナを削除してもデータを残す方法
  • ホストとコンテナでファイルを共有する方法
  • バインドマウントと名前付きボリュームの違い
  • PostgreSQLのデータ永続化

データ管理の重要な概念を習得しましょう!

📝

学習メモ

Docker・コンテナ技術入門 - Step 9

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE