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

Dockerログ掃除の完全ガイド:json.logによるディスク圧迫を防ぐ5つの方法

午前3時17分。
「本番サーバーのディスク使用率が100%です。全サービスが応答しません」という真っ赤なアラートで叩き起こされました。

冷や汗をかきながらSSHで入り、df -h を叩くと、確かにルートパーティションが満杯です。犯人探し(duコマンド)をした結果、/var/lib/docker/containers/ の下にある、たった一つの xxx-json.log ファイルが82GB にも膨れ上がっているのを見つけました。

82GB
ログファイルサイズ
来源: 1つのコンテナのjson.logが82GBに達し、ディスクを食いつぶしていた実例

「コンテナは動いているのになぜ?」と思いましたが、これはDockerの仕様です。デフォルトでは、Dockerはログファイルのサイズを制限しません。 アプリが吐き出す標準出力(stdout)は全て json.log に書き込まれ、ディスクがいっぱいになるまで無限に増え続けるのです。

この記事では、私がその夜に行った「緊急ディスク解放手順」と、二度と同じ悲劇を繰り返さないための「恒久的なログ管理設定」を解説します。

なぜDockerログはディスクを食いつぶすのか(仕組み)

コンテナが console.logprint で出力した内容は、Dockerによってホスト側のJSONファイルに記録されます。
場所は通常ここです:/var/lib/docker/containers/<ID>/<ID>-json.log

問題は、「ログローテーション(一定サイズで古いものを消す機能)」がデフォルトで無効 なことです。
秒間100行のログを吐くWebアプリなら、1日800MB、1ヶ月で25GBになります。もしDEBUGモードで動かしっぱなしなら、数日でディスクがパンクします。

特に危険なのは以下のケースです:

  1. 無限エラーログ:DB接続エラーなどでアプリが死なずにエラーを吐き続ける場合。
  2. ログレベル設定ミス:本番環境なのにDEBUGレベルになっている。
  3. 大流量アプリ:アクセスログだけでギガ単位になる場合。

緊急対応:今すぐディスクを空ける方法

ディスクが満杯なら、まずは空き容量を作ってサービスを復旧させるのが先決です。

1. 巨大なログファイルを見つける

find /var/lib/docker/ -name "*.log" -exec ls -sh {} \; | sort -h -r | head -20

これでトップ20の巨大ログファイルが見つかります。

2. ファイルを「安全に」空にする

絶対にやってはいけないことrm コマンドでログファイルを削除する。
これをやるとファイルは消えますが、Dockerプロセスがファイルハンドル(掴んでいる手)を離さないため、ディスク容量は解放されません。最悪、Dockerの再起動が必要になります。

正しいやり方:ファイルの中身だけを空にします。

方法1:truncateコマンド(推奨)

truncate -s 0 <ログファイルのパ>
# 例
truncate -s 0 /var/lib/docker/containers/abc123.../abc123...-json.log

これはファイルサイズを0バイトに切り詰めるコマンドで、プロセスに影響を与えず安全です。

方法2:リダイレクトを使う

cat /dev/null > <ログファイルのパ>

これも同じ効果があります。

一括削除コマンド(自己責任で):

sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'

全てのコンテナのログをリセットします。本当に緊急の場合のみ使ってください。

恒久対策:ログローテーションを設定する

緊急対応が終わったら、再発防止策を打ちましょう。Dockerに「ログが大きくなりすぎたら古いものを捨てて」と教える設定です。

全コンテナに一括適用(daemon.json)

/etc/docker/daemon.json を編集(なければ作成)します。

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

パラメータの意味:

  • max-size: 1ファイルあたりの最大サイズ。これを超えると新しいファイルが作られます。
  • max-file: ログファイルを何世代残すか。
  • compress: 古いログを圧縮して保存するか。

この設定だと、100MB × 3 = 最大300MB しかディスクを使いません。

注意点:
設定後、Dockerを再起動 (systemctl restart docker) する必要があります。
さらに重要なのは、この設定は「新しく作られるコンテナ」にのみ適用されます。 既存のコンテナには反映されないので、docker stop & docker rm して作り直す必要があります。

個別のコンテナに設定する

特定のコンテナ(例えばNginx)だけ設定したい場合は、起動時に指定します。

docker run の場合:

docker run -d \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  nginx

docker-compose.yml の場合:

version: '3.8'
services:
  web:
    image: nginx
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

ログドライバーの選び方

デフォルトの json-file 以外にも、ログの保存方法は選べます。

1. json-file(デフォルト・標準)

  • メリットdocker logs コマンドが使える。設定が簡単。
  • デメリット:ローテーション設定を忘れると死ぬ。
  • 推奨:小〜中規模な環境、開発環境。

2. local(おすすめ)

Docker 18.09から導入された、より高速で効率的なドライバーです。
デフォルトでログローテーションが有効(100MB x 5)になっているのが最大の特徴です。

設定 (daemon.json):

{
  "log-driver": "local"
}

これにするだけで、もうディスク容量を気にする必要がなくなります。

3. syslog / journald

システムログやjournaldに転送します。

  • メリット:OSのログ管理と統合できる。
  • デメリットdocker logs コマンドでログが見れなくなる場合がある(syslogなど)。

生き残るための運用ベストプラクティス

  1. 本番環境では必ず制限する
    daemon.json でグローバルに max-size: 100m を入れておくのが一番安全です。

  2. ログレベルを適切に
    本番環境で DEBUG ログを出してはいけません。INFOWARN にしましょう。

  3. ディスク監視を入れる
    Prometheusなどでディスク使用率を監視し、80%を超えたらアラートが飛ぶようにしましょう。

  4. アプリ側でログを出しすぎない
    巨大なJSONやバイナリデータをログに出力するのはやめましょう。

まとめ

あの夜の82GBのログファイルは、私のDocker運用における最大の教訓でした。

やるべきことリスト:

  1. 今すぐ find コマンドで巨大ログがないかチェックする。
  2. daemon.json にログローテーション設定が入っているか確認する。
  3. 入っていなければ設定してDockerを再起動し、コンテナを再作成する。

これだけで、将来の深夜の呼び出しを一回減らすことができます。

Dockerログ一掃とディスク解放手順

ディスクを圧迫する巨大ログファイルの安全な削除方法と、再発防止のためのローテーション設定

⏱️ Estimated time: 20 min

  1. 1

    Step1: ステップ1:巨大ログファイルの特定

    コマンド:find /var/lib/docker/ -name "*.log" -exec ls -sh {} ; | sort -h -r | head -10
    解説:コンテナIDごとのjson.logファイルをサイズ順にリストアップし、ディスクを圧迫している元凶を見つけます。
  2. 2

    Step2: ステップ2:ログの安全な削除(truncate)

    コマンド:truncate -s 0 <ログファイルのパス>
    解説:rmで削除してはいけません(プロセスが掴んだままだと容量が空きません)。truncateでサイズを0にすることで、コンテナを停止せずに即座に容量を解放できます。
  3. 3

    Step3: ステップ3:再発防止(ログローテーション設定)

    設定:/etc/docker/daemon.json に以下を追加
    {
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "50m",
    "max-file": "3"
    }
    }
    解説:1ファイル50MB、最大3世代までに制限します。
  4. 4

    Step4: ステップ4:設定の適用

    コマンド:systemctl restart docker して、既存コンテナを再作成(Recreate)
    解説:daemon.jsonの設定は「新規作成されるコンテナ」にのみ有効です。既存のコンテナは作り直すまで古い設定のままなので注意してください。

FAQ

ログファイルをrmコマンドで削除しても容量が空きません。
Linuxの仕様です。実行中のプロセス(Docker)が開いているファイルを削除しても、プロセスが終了するまでディスク領域は解放されません。`rm` ではなく `truncate -s 0 <ファイル>` または `cat /dev/null > <ファイル>` を使って中身を空にするか、Dockerサービスを再起動してください。
ログローテーション設定はコンテナ再起動で反映されますか?
いいえ、反映されません。`docker restart` では設定は変わらず、`docker rm` して `docker run` で作り直す(再作成する)必要があります。docker-composeの場合は `up -d --force-recreate` が有効です。
最適なログドライバーは何ですか?
単にディスク圧迫を防ぎたいなら `local` ドライバーがおすすめです(デフォルトでローテーション有効、高速)。ログ収集基盤(ELKなど)がない小規模環境なら、デフォルトの `json-file` に `max-size` 制限をかけるのが最も手軽で互換性が高いです。

3 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日

コメント

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

関連記事