言語を切り替える
テーマを切り替える

Docker ログ管理の実践:ドライバー設定から集中収集まで

スマホが振動した。本番サーバーのディスクアラート——閾値 85%。

ノート PC を開いて SSH で入る。df -h を見ると、ルートパーティションの空きは 12% だけ。あちこち調べた末、犯人は /var/lib/docker/containers にいた。2 週間動き続けた Nginx コンテナのログが、すでに 12GB に膨れ上がっていた。

Docker はデフォルトでログサイズを制限しない——これを知らない人は多い。あのコンテナは毎日数万件のアクセスログを吐き、json-file ドライバーが忠実に全部記録し、2 週間でディスクを埋め尽くした。

その場ではログファイルを削除し、全コンテナにローテーション設定を追加した。対応が終わったのは午前 4 時ごろだった。

あの夜以降、1 週間かけて Docker ログ管理を体系的に整理した——ドライバー選定、ローテーション設定、マルチコンテナ環境での集中収集まで。この記事は、そのとき踏んだ坑のまとめです。

一、Docker ログドライバーの全体像

まず前提から。Docker コンテナのログは適当に書かれるわけではなく、「ログドライバー」が保存先と形式を決めます。

Docker は複数のログドライバーをサポートし、それぞれ向く場面が異なります。コンテナ実行時のデフォルトは json-file——stdout と stderr を JSON 形式でローカルファイルに書き込みます。保存先は /var/lib/docker/containers/<コンテナID>/<コンテナID>-json.log です。

json-file の利点はシンプルさ。追加設定不要、形式が統一され、docker logs でそのまま読める。反面、落とし穴もはっきりしている——デフォルトではサイズ上限がない。コンテナが動き続ける限りログも増え続け、いずれディスクがパンクする。

よく使う 6 種類を表にまとめました。

ドライバー向く場面構造化外部サービス性能への影響
json-file開発・デバッグ、単機デプロイあり(自動 JSON)不要
syslog既存 syslog 基盤がある企業なし(要パース)あり(rsyslog)
journaldsystemd 環境一部不要
fluentdクラウドネイティブ可観測性、ログ集中収集あり(カスタム tag)あり(Fluentd)
gelfGraylog 利用者ありあり(Graylog)
noneログ無効、一時コンテナなし不要なし

json-file と syslog が最もよく選ばれます。json-file はローカルデバッグや軽量デプロイ向け。syslog は rsyslog や syslog-ng へ直接流し、集中ログ基盤で扱う企業向けです。

journald はログを systemd journal に渡します。systemd でサービス管理しているサーバー(現代の Linux ディストリビューションの大半)なら、journalctl で見られるので便利です。

fluentd と gelf は集中収集向け。fluentd は Elasticsearch、Kafka、クラウドストレージなど多様なバックエンドへ転送できます。gelf は Graylog 専用形式。どちらもマルチコンテナクラスタ向きですが、収集基盤の別途構築が必要です。

none はログ自体を無効化。一時コンテナやバッチでログが不要なら、リソース節約に使えます。

選び方の目安

  • 単機・開発:json-file で十分(ローテーションは次章)
  • 企業に syslog 基盤あり:syslog で既存資産を活用
  • クラスタでログを一元閲覧:fluentd または Loki(後述)
  • 一時コンテナでログ不要:none

二、ログローテーション設定の実践

冒頭の問題——12GB に膨れたログ——をどう防ぐか。答えはローテーションパラメータです。

json-file がサポートする 3 つのキーパラメータ:

  • max-size:単一ログファイルの上限。超えると新ファイルを作り、旧ファイルは番号付きで残る。例:max-size=10m なら 1 ファイル最大 10MB。
  • max-file:保持する履歴ファイル数。上限を超えた最古ファイルは削除。例:max-file=3 なら履歴 3 つ + 現行 1 つ。
  • compress:ローテーション後の旧ファイルを圧縮するか。デフォルト false。true にするとディスクは節約できるが、CPU 負荷はわずかに増える。

この 3 つで占有容量を抑えられます。max-size=10m, max-file=3 なら最大約 30MB(圧縮すればさらに小さく)。

設定の 3 レイヤー:グローバル vs 単体

1. グローバル設定(daemon.json)

全コンテナに一括適用。/etc/docker/daemon.json に追加:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "compress": "true"
  }
}

編集後、sudo systemctl restart docker で反映。以降に作る新規コンテナはこの設定を継承します。

注意:既存コンテナには効きません。個別対応するか、削除して作り直してください。

2. 単体設定(docker run)

特定コンテナだけパラメータを変えたいとき:

docker run -d \
  --name nginx \
  --log-driver json-file \
  --log-opt max-size=50m \
  --log-opt max-file=5 \
  --log-opt compress=true \
  nginx:alpine

高トラフィックなら max-size=50m, max-file=10 のように緩めてもよいでしょう。

3. Docker Compose

本番ではいちばんよく使うのがこれです:

version: "3.9"
services:
  webapp:
    image: webapp:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
        compress: "true"

  nginx:
    image: nginx:alpine
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "5"

サービスごとに個別設定でき、柔軟性が高い。

本番向けの目安

SigNoz の 2024 年ガイドでは次のような値が示されています。

  • 開発・テストmax-size=10m, max-file=3 —— 足りれば OK
  • 中程度のトラフィックmax-size=50m, max-file=5 —— 調査用に履歴を多めに
  • 高トラフィックmax-size=100m, max-file=10 —— ローテが速すぎて履歴が消えるのを防ぐ

具体的な数値は業務次第。原則は、ディスク容量とログの重要度のバランス。ディスクに余裕がありログが重要なら多めに、逆なら絞る。

三、集中ログ収集ソリューションの比較

単機ならローテーションで足ります。コンテナが十数〜数十台に及ぶと、ログが各ホストに散らばり、docker logs を一台ずつ見るのは地獄です。

集中収集は、全コンテナのログを一か所に集め、保存・検索を統一する仕組みです。

主流は大きく 3 系統。

ELK Stack(Elasticsearch + Logstash + Kibana)

古典的な定番。Logstash が収集、Elasticsearch が保存・索引、Kibana が可視化クエリ UI。

全文検索、複雑クエリ、ダッシュボード——機能は強力でエコシステムも成熟。反面、Elasticsearch は重量級でメモリ数 GB は珍しくない。Logstash も設定・学習コストが高い。

専門運用チームがあり、ログ量が多く高度な検索が必要な大企業向け。

EFK(Logstash の代わりに Fluentd)

ELK の Logstash を Fluentd に置き換えた構成。Fluentd は数百 MB 程度で、プラグインも豊富。

設定は Logstash よりすっきりしますが、Elasticsearch の重さは変わらない。中〜大規模チーム向け。

Loki + Promtail + Grafana

Grafana Labs 製。全文索引は作らず、コンテナ名などのラベルだけ索引し、本文は圧縮ファイルに保存。クエリは grep 的にマッチさせる設計で、十分速い。

その結果、Loki は極めて軽量——メモリ数百 MB、ストレージコストも Elasticsearch より低い。Promtail がエージェント、Grafana が UI で一体運用。

Kubernetes などクラウドネイティブ、予算の限られた小規模チームにコスパが良い。

比較表

ソリューションメリットデメリット向く規模コスト
ELK機能が強力、クエリ柔軟、エコシステム成熟リソース消費大、設定複雑、ストレージ高コスト大企業
EFKFluentd が軽量、プラグイン豊富Elasticsearch は依然として重い中〜大中〜高
Loki極めて軽量、低コスト、クラウドネイティブ向きクエリ機能は限定的、全文検索向きでない小規模/K8s

選定の目安

  • 小規模(10 人未満)・予算限り:Loki。構築が簡単、Grafana UI も使いやすい
  • 中規模(10〜50 人)・運用リソースあり:ログ量次第で Loki か EFK
  • 大企業・専門運用:ELK。投資に見合う機能とエコシステム

すでに Grafana でメトリクス監視しているなら、Loki はほぼ自然な拡張——同じ画面で指標とログを見られます。

四、本番環境で踏みやすい坑

最後に、自分が踏んだ坑を共有します。

1. ローテーション未設定でディスク満杯

いちばん多いパターン。デプロイ時にログを考えず、数ヶ月後のアラートで初めて数十 GB のログファイルに気づく。

対策daemon.json にグローバルデフォルトを入れ、新規コンテナに自動継承させる。毎回 docker run で付け忘れない——人は忘れる、設定は忘れない。

2. コンテナ再起動でログ消失

json-file では、コンテナ削除と同時にログファイルも消えます。docker restart ではなく docker rm + docker run で再起動すると、履歴ログは消えます。

深夜クラッシュ後に「直前のログ」を見たいのに、すでに再作成済みでログがない——よくある悲劇です。

対策

  • 再起動は docker restart を優先
  • 重要アプリは fluentd/syslog で外部へ転送
  • 本番ログは定期的にバックアップ

3. Fluentd アドレスの設定ミス

fluentd ドライバーは TCP で Fluentd に送ります。アドレスが誤ってもコンテナは起動しますが、ログは届かない——集中基盤にあると思い込んで、実は転送途中で失われている。

設定例:

docker run -d \
  --log-driver fluentd \
  --log-opt fluentd-address=127.0.0.1:24224 \
  --log-opt tag="docker.{{.Name}}" \
  my-web-app

fluentd-address は Fluentd の実際のリッスンアドレスと一致させます。デフォルトポート 24224、TCP。

調査手順

  • Fluentd 稼働確認:curl http://localhost:24224 または netstat -tlnp | grep 24224
  • docker inspect <コンテナID> で LogConfig を確認
  • Fluentd 側ログで Docker からのストリーム受信を確認

4. 監視とアラート

設定して終わりではありません。

2 つの重要指標

  • ディスク容量/var/lib/docker/containers のサイズを定期確認。10GB 超で通知、など
  • ログ遅延:集中収集では Fluentd/Loki の書き込み遅延。高い場合はネットワークかストレージのボトルネック

Prometheus + Grafana でも、Cron + シンプルスクリプトでも構いません。

まとめ

Docker ログ管理の要点:

  1. ドライバー選定:汎用は json-file、企業基盤は syslog、集中収集は fluentd
  2. ローテーションmax-size + max-file、グローバルで楽、単体で柔軟
  3. 集中収集:小規模は Loki、大企業は ELK——規模と予算で決める
  4. 坑回避:グローバルローテーション、ログ消失防止、Fluentd アドレス確認、ディスク監視

クイック設定テンプレート:

// /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "compress": "true"
  }
}

今すぐやること:ローテーション未設定なら、/var/lib/docker/containers に巨大ログがないか確認し、daemon.json に上記を入れて Docker を再起動。数分の作業で、深夜 2 時のディスクアラート対応を避けられます。

Docker ログローテーション設定

Docker コンテナにログローテーションを設定し、ログファイルによるディスク枯渇を防ぐ

⏱️ 目安時間: 10 分

  1. 1

    ステップ1: 現在のログ状態を確認

    以下のコマンドで、コンテナログの使用状況を確認します:

    ```bash
    # ログディレクトリの合計サイズ
    du -sh /var/lib/docker/containers

    # 各コンテナのログサイズ
    docker ps -q | xargs -I {} sh -c 'echo -n "{}: "; docker inspect --format="{{.LogPath}}" {} | xargs du -sh 2>/dev/null || echo "N/A"'
    ```

    あるコンテナのログが 1GB を超えていたら、ローテーション設定が必要です。
  2. 2

    ステップ2: グローバルデフォルトのローテーションを設定

    `/etc/docker/daemon.json` を編集し、ログドライバー設定を追加します:

    ```json
    {
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "compress": "true"
    }
    }
    ```

    パラメータの意味:
    - max-size: 単一ファイル最大 10MB
    - max-file: 履歴ファイルを 3 つ保持
    - compress: 古いファイルを圧縮して容量を節約
  3. 3

    ステップ3: Docker を再起動して反映

    再起動コマンドで設定を有効にします:

    ```bash
    sudo systemctl restart docker
    ```

    **注意**:グローバル設定は新規コンテナにのみ適用されます。既存コンテナは再作成するか、個別に設定してください。
  4. 4

    ステップ4: 設定を検証

    テストコンテナを作成し、設定が反映されているか確認します:

    ```bash
    # テストコンテナを作成
    docker run -d --name test-nginx nginx:alpine

    # ログ設定を確認
    docker inspect --format='{{.HostConfig.LogConfig}}' test-nginx
    ```

    出力に `max-size=10m,max-file=3` が表示されれば OK です。
  5. 5

    ステップ5: 既存コンテナのログをクリーンアップ(任意)

    既存コンテナのログが大きすぎる場合は、手動でクリーンアップできます:

    ```bash
    # 方法1:ログファイルを空にする(コンテナは再起動しない)
    sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' コンテナ名)

    # 方法2:コンテナを再作成(推奨)
    docker rm -f コンテナ名
    docker run ... # ログパラメータを付けて再作成
    ```

    再作成後、新しいコンテナはグローバル設定を継承します。

FAQ

Docker のデフォルトログドライバーは何ですか?なぜサイズ制限がないのですか?
Docker はデフォルトで json-file ドライバーを使い、コンテナの stdout と stderr を JSON 形式でローカルファイルに書き込みます。デフォルトでサイズ制限がないのは、ログの完全性を保ち、調査に必要な情報を失わないためです。一方で、長期稼働するコンテナのログは際限なく増えるため、ローテーションパラメータを手動で設定する必要があります。
max-size と max-file はどう組み合わせるのが合理的ですか?
おすすめの組み合わせ:開発環境は `max-size=10m, max-file=3`(合計約 30MB)、本番環境は `max-size=50m, max-file=5`(合計約 250MB)、高トラフィックアプリは `max-size=100m, max-file=10`(合計約 1GB)。ディスク容量と調査ニーズのバランスが重要です。
コンテナ削除後もログは残りますか?永続化するには?
json-file ドライバーでは、コンテナ削除時にログファイルも一緒に消えます。永続化の方法:1)fluentd/syslog ドライバーで外部ストレージへ転送、2)`/var/lib/docker/containers` を定期的にバックアップ、3)再起動は削除・再作成ではなく `docker restart` を使う。
ELK と Loki はどう選びますか?小規模チーム向けは?
小規模チーム(10 人未満)には Loki がおすすめです。デプロイが簡単で、メモリは数百 MB 程度、ストレージコストも低く、Grafana とシームレスに連携できます。ELK は機能が強力ですがリソース消費が大きく(Elasticsearch のメモリは数 GB になることも)、専門運用チームのある大企業向けです。すでに Grafana で監視しているなら、Loki が自然な選択です。
Fluentd のアドレス設定を間違えるとどうなりますか?どう調査しますか?
アドレスが誤っているとコンテナは起動しますがログは収集されず、調査時に初めて欠落に気づくことがあります。手順:1)Fluentd の稼働確認 `netstat -tlnp | grep 24224`、2)コンテナのログ設定確認 `docker inspect --format='{{.HostConfig.LogConfig}}' コンテナID`、3)Fluentd 側ログで Docker からのデータストリーム受信を確認。
既存コンテナに新しいログローテーション設定を適用するには?
グローバル設定 `daemon.json` は新規コンテナにのみ有効です。既存コンテナの対処:1)再作成(推奨):`docker rm -f コンテナ名` のあと新設定で再作成、2)単体設定:`docker update --log-opt max-size=10m コンテナ名`(一部パラメータはホット更新可)、3)手動クリア:`truncate -s 0 $(docker inspect --format='{{.LogPath}}' コンテナ名)`。
Docker ログのディスク使用量をどう監視しますか?
監視の例:1)シンプルなスクリプト + Cron で定期的に `du -sh /var/lib/docker/containers` を実行し、閾値超過で通知、2)Prometheus + node_exporter でディスク使用率を監視、3)Loki/Fluentd などログ基盤の書き込み遅延指標を利用。ディスクアラート(例:10GB 超で通知)を設定し、深夜の緊急対応を避けましょう。

4分で読めます · 公開日: 2026年4月30日 · 更新日: 2026年6月8日

関連記事

コメント

GitHubアカウントでログインしてコメントできます