Dockerログ削除の完全ガイド:json.log でディスクがあふれない 5 つの方法
クイック結論(先に止血、あとで恒久対策)
Docker ログでディスクが逼迫したとき、効果的な順序は次のとおりです。
まず truncate で止血して容量を確保し、次に max-size + max-file でローテーションを設定し、最後にコンテナを再作成して設定を反映します。
削除だけでは再発します。設定だけでは、既存コンテナはこれまでどおり肥大化します。
午前 3 時 17 分、スマホの振動で浅い眠りから引きずり出されました。
画面には刺さるような赤いアラート——「本番サーバーのディスク使用率 100%、すべてのサービスが応答停止」。心臓が冷えました。数十万ユーザー規模の EC プラットフォームで、1 分の停止がそのまま売上損失になります。
すぐ SSH で入り、df -h を実行。ルートパーティションは本当に満杯でした。調査の末、犯人は /var/lib/docker/containers/ 配下——あるコンテナの xxx-json.log が 82GB だったのです。
コンテナは普通に動いているのに、なぜログだけこんなに?——当時は本当に戸惑いました。
後から分かったのですが、これは珍しい話ではありません。Docker はデフォルトでログファイルサイズを制限しません。stdout と stderr の出力はすべて json.log に書き込まれ、増え続け、増え続け、ディスクが満杯になるまで止まりません。
Docker ログに振り回されているなら、安心してください。この記事では、巨大ログの応急削除、再発防止のローテーション設定、自分に合うログドライバーの選び方をまとめます。私が踏んだ落とし穴もすべて書いてあるので、同じ轍を踏まないでほしいです。
なぜ Docker ログはディスクを食いつぶすのか
Docker のログ保存の仕組み
まず、Docker がログをどう扱うかから。
コンテナが console.log()、System.out.println() などで stdout / stderr に出力すると、Docker はそれを JSON 形式のログファイルに書き込みます。場所は /var/lib/docker/containers/<container-id>/<container-id>-json.log です。
一見問題なさそうですが——Docker はデフォルトでログローテーションを行いません。
つまりログファイルは分割も削除もされず、増え続けるだけ。1 日 1GB なら 1 週間で 7GB、1 ヶ月で 30GB。ログレベルが DEBUG など「おしゃべり」なアプリなら、さらに速く膨らみます。
ざっくり計算すると、中規模トラフィックの Web アプリが秒間 100 行、1 行平均 100 バイトのログを出す場合:
100行/秒 × 86400秒 × 100バイト ≈ 864MB/日 ≈ 25GB/月
同じ規模のコンテナが 10 個あれば、1 ヶ月もしないうちに 100GB ディスクは満杯になります。しかも控えめな見積もりです。
ハマりやすいシーン
自分と周りの経験から、特に危ないのは次のパターンです。
1. ログレベルが低すぎる
開発では DEBUG や INFO で問題なくても、本番にそのまま持ち込むと、HTTP リクエストごとに大量のデバッグ情報が出ます。ログが暴走します。
極端な例として、Node.js サービスがリクエストボディ全体(画像アップロードの base64 など)をログに書いていたケースがあります。1 リクエスト数 MB。3 日で 200GB ディスクが満杯でした。
2. ループするエラー出力
バグで無限ループし、例外とスタックトレースを吐き続けると、ログの増え方は恐ろしいです。
あるマイクロサービスは DB 接続プールの設定ミスで、毎秒数百回リトライし、毎回フルスタックを出力。3 時間で 2GB から 120GB まで膨らみ、ディスクごと落ちました。
3. 長期稼働の本番コンテナ
数ヶ月〜数年、ローテーションなしで動かし続けると、ログの累積は相当な量になります。
引き継いだプロジェクトでは、8 ヶ月稼働の Nginx コンテナのログが 150GB。docker logs も巨大ファイルを読むため、かなり重くなります。
4. 高トラフィックアプリ
アクセスが多ければログも多い。日 PV 数百万クラスでも、1 リクエスト 1 行の access ログだけで天文学的な量になります。
多くの人は気づかないまま運用し、ある日深夜にディスク満杯でシステムが落ちて、初めて Docker ログの罠に気づきます。
応急削除:すぐにディスク容量を確保する
ディスクが満杯でサービスが落ち、チャットで上司から @ が飛んできた——そんなときは慌てず、まず容量を空けましょう。
ステップ 1:犯人を特定する
どのログが大きいか知る必要があります。次を実行:
find /var/lib/docker/ -name "*.log" -exec ls -sh {} \; | sort -h -r | head -20
サイズ順に上位 20 件が表示されます。例:
82G /var/lib/docker/containers/a1b2c3d4.../a1b2c3d4...-json.log
35G /var/lib/docker/containers/e5f6g7h8.../e5f6g7h8...-json.log
12G /var/lib/docker/containers/i9j0k1l2.../i9j0k1l2...-json.log
...
最大のものの container ID(長い文字列)をメモします。
特定コンテナのログパスは次でも確認できます:
docker inspect --format='{{.LogPath}}' <container_name_or_id>
例:
docker inspect --format='{{.LogPath}}' nginx
# 出力:/var/lib/docker/containers/abc123.../abc123...-json.log
ステップ 2:安全にログを空にする
重要:いきなり rm でログファイルを削除しないでください。
私も最初は rm -f xxx-json.log を試し、Docker が混乱しました。Docker プロセスはファイルハンドルを保持したままなので、削除してもプロセスは書き込みを続け、ディスク容量は解放されません。
正しいのはファイルを削除するのではなく、中身を空にすることです。
方法 1:cat で空にする
cat /dev/null > $(docker inspect --format='{{.LogPath}}' <container_id>)
空内容を書き込むので、ファイルは残りサイズは 0。Docker プロセスは影響を受けません。
nginx コンテナの例:
cat /dev/null > $(docker inspect --format='{{.LogPath}}' nginx)
方法 2:truncate(推奨)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_id>)
truncate はファイルを切り詰める専用コマンドです。-s 0 で 0 バイトにします。
nginx の例:
truncate -s 0 $(docker inspect --format='{{.LogPath}}' nginx)
方法 3:全コンテナのログを一括で空にする
すべてのコンテナログが巨大な場合:
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'
注意:全コンテナのログが消えます。本当に緊急のときだけ。履歴が必要なら 1 つずつ削除する方が安全です。
効果を確認する
削除後、df -h でディスクを確認:
df -h /var/lib/docker/
使用率が下がっているはずです。下がらない場合は、まだ DEBUG ログを吐いている、ループエラーが続いているなど、アプリ側の問題を先に止める必要があります。
82GB のログを空にしたとき、使用率は 100% から 60% まで一気に下がり、サービスはすぐ復旧しました。ただしこれは対症療法。恒久対策としてログローテーションが必要です。
根本対策:ログローテーションを設定する
応急削除は一時しのぎです。Docker にログサイズを自動管理させ、無限増殖を止めましょう。
グローバル設定:daemon.json を編集
最も一般的な方法は、Docker のグローバル設定でローテーションを指定することです。
設定ファイル:/etc/docker/daemon.json
存在しなければ作成し、次を追加:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
各パラメータの意味:
- max-size:1 ファイルの上限。到達すると新ファイルにローテーション
- max-file:保持するログファイル数。超過分は最古を削除
- compress:ローテーション後の古いログを圧縮するか
この設定なら、1 コンテナあたり最大 10MB × 3 = 30MB(圧縮前)程度です。
本番環境の推奨値:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"compress": "true"
}
}
max-size: "100m" で調査用の履歴を多めに残し、max-file: "3" で直近 300MB 相当を保持します。
状況に応じた調整例:
- ログ量少:
max-size: "10m",max-file: "3" - 中程度:
max-size: "50m",max-file: "3" - 多い:
max-size: "100m",max-file: "5"
重要:値はすべて引用符付き文字列です。"max-size": 10m(引用符なし)はエラーになります。
Docker を再起動して反映
daemon.json 変更後は再起動が必要:
sudo systemctl restart docker
ただし——この設定は新規作成されるコンテナにのみ有効です。既存コンテナには効きません。再作成が必要です。
docker run の場合:
docker stop <container_name>
docker rm <container_name>
docker run [元の引数] <image>
docker-compose の場合:
docker-compose down
docker-compose up -d
down でコンテナを削除し、up -d で新設定のコンテナを作り直します。
単一コンテナ向けの設定
グローバルを変えず、特定コンテナだけ制限したい場合:
docker run:
docker run -d \
--name my-app \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:latest
docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
compress: "true"
コンテナごとにポリシーを分けられます。例:
- Nginx:ログ多め →
max-size: "50m",max-file: "5" - 軽い cron ジョブ:
max-size: "5m",max-file: "2"
設定が効いているか確認
docker inspect で LogConfig を確認:
docker inspect <container_name> | grep -A 10 LogConfig
期待する出力例:
"LogConfig": {
"Type": "json-file",
"Config": {
"max-file": "3",
"max-size": "10m",
"compress": "true"
}
}
{} の空オブジェクトなら、まだデフォルト(無制限)です。コンテナを再作成してください。
設定後は全コンテナのログ設定をチェックする小さなスクリプトを書き、漏れがないか確認するのがおすすめです。
ログドライバー選択ガイド
ここまではデフォルトの json-file 前提でした。Docker には複数のログドライバーがあり、用途ごとに向き不向きがあります。
json-file(デフォルト)
Docker の標準選択肢です。
メリット:
docker logsが使え、トラブルシュートが楽max-sizeとmax-fileを足すだけで設定しやすい- ローカル保存でアクセスが速い
デメリット:
- デフォルトではローテーションなし——今日の主題そのもの
- ホストに保存されるため、コンテナ削除でログも消える
向いているシーン:ローテーションを設定すれば、多くの環境で十分。
推奨設定:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3",
"compress": "true"
}
}
local ドライバー(推奨)
Docker 18.09 以降なら、こちらを強くおすすめします。
メリット:
- 自動ローテーション——手動設定なしでもサイズ制限
- json-file より効率的なフォーマットで性能が良い
docker logsも利用可能
デメリット:
- Docker 18.09 以上が必要
- バイナリ形式のため
catでは読めない(通常は問題にならない)
向いているシーン:本番環境。手間が少なく性能も良い。
設定例:
{
"log-driver": "local",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
新規プロジェクトでは json-file より local を選ぶことが多いです。
journald ドライバー
systemd 系(Ubuntu 16.04+、CentOS 7+ など)向け。
メリット:
- OS ログと統合管理
- 自動ローテーション
- コンテナ ID などメタデータ付きの構造化ログ
docker logsとjournalctlの両方が使える
デメリット:
- systemd 環境限定
- journald に慣れていないと学習コストあり
向いているシーン:すでに systemd / journald ベースの運用体系がある場合。
設定例:
{
"log-driver": "journald"
}
journalctl で確認:
journalctl -u docker.service -f CONTAINER_NAME=my-app
syslog ドライバー
ログを syslog サーバーへ転送します。
メリット:
- リモート syslog で集中管理
- TCP / UDP 対応(TCP の方が信頼性高い)
- 既存 syslog 基盤と統合しやすい
デメリット:
docker logsが使えない——現場調査が不便- ネットワーク遅延の可能性
- syslog サーバーの運用が必要
向いているシーン:大規模クラスタで syslog 集中ログ基盤がすでにある場合。
設定例:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://192.168.1.100:514",
"syslog-facility": "daemon",
"tag": "{{.Name}}/{{.ID}}"
}
}
特別な理由がなければ、syslog はあまり推奨しません。docker logs が使えないのは地味に痛いです。
選び方の目安
| シーン | 推奨ドライバー | 理由 |
|---|---|---|
| 単機・小規模クラスタ | local または json-file + ローテーション | シンプルで docker logs も使える |
| systemd 環境 | journald | OS ログと統合 |
| 大規模クラスタ | fluentd / loki + ローカルドライバー | 集中ログ + ローカル応急用 |
| 既存 syslog あり | syslog + ローカル | リモートとローカルの二重化 |
私の運用:小規模は local、大規模は json-file + Loki で集中管理し、ローカルには直近数百 MB を残して応急調査用にしています。
どのドライバーでも、ローカルログのサイズ上限は必須です。無制限はいずれディスクを破綻させます。
ベストプラクティスと運用のコツ
目の前の問題を片付けたら、長期運用の話をしましょう。
本番環境チェックリスト
本番を担当するなら、次を順に確認してください。
1. グローバルログ設定
{
"log-driver": "local",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
または json-file:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3",
"compress": "true"
}
}
2. 全コンテナの設定確認
全コンテナにローテーションが効いているか確認するスクリプト:
#!/bin/bash
for container in $(docker ps -q); do
name=$(docker inspect --format='{{.Name}}' $container | sed 's/\///')
logconfig=$(docker inspect --format='{{json .HostConfig.LogConfig}}' $container)
echo "コンテナ: $name"
echo "ログ設定: $logconfig"
echo "---"
done
漏れがないか必ず実行。
3. 監視アラート
ディスク満杯になってからでは遅い。先にアラートを:
- ディスク使用率 > 80%:警告
- ディスク使用率 > 90%:重大
/var/lib/docker/containers/のサイズが閾値超:警告
Prometheus + Grafana + Alertmanager の例:
- alert: HighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes > 0.8
for: 5m
annotations:
summary: "ディスク使用率が 80% を超えました"
4. 定期巡検
週次または月次でログチェック:
# Docker ディレクトリ全体
du -sh /var/lib/docker/
# コンテナログディレクトリ
du -sh /var/lib/docker/containers/
# 最大の json.log 上位 10 件
find /var/lib/docker/containers/ -name "*-json.log" -exec du -h {} \; | sort -h -r | head -10
異常があればすぐ対処。
アプリ層の最適化
インフラだけでなく、アプリ側も協力が必要です。
1. ログレベルの調整
本番で DEBUG / INFO は多すぎます。目安:
- 本番:WARN または ERROR
- テスト:INFO
- 開発:DEBUG
これだけでログ量は 80% 以上減ることもあります。
2. 専用ログ基盤の利用
ログ量が非常に多いアプリは Docker ログだけに頼らない:
- ELK(Elasticsearch + Logstash + Kibana)
- Loki + Grafana(軽量)
- マネージドのクラウドログ(AWS CloudWatch Logs、Google Cloud Logging など)
Docker ログは直近の少量だけ残し、応急調査用に。
3. 構造化ログ
JSON 形式で出力すると分析しやすい:
// 悪い例
console.log("ユーザーのログインに成功しました。ユーザー ID: " + userId);
// 良い例
console.log(JSON.stringify({
level: "info",
event: "user_login",
userId: userId,
timestamp: new Date().toISOString()
}));
4. ログサンプリング
リクエストログが多すぎる場合:
// 10% のリクエストだけ記録
if (Math.random() < 0.1) {
console.log("HTTPリクエスト詳細...");
}
エラー時だけ詳細を出す方法も有効:
if (error) {
console.log("詳細リクエスト情報: ", requestDetails);
}
よくある質問(FAQ)
Q1: daemon.json 変更後の Docker 再起動は稼働中コンテナに影響する?
A: コンテナは停止しません。ただし設定は新規コンテナのみ有効で、既存は再作成が必要です。
Q2: ログを空にするとアプリに影響する?
A: ありません。Docker がハンドルを保持したまま書き込みを続けるため、アプリは気づきません。
Q3: log-driver=journald なら max-size も必要?
A: 不要です。journald が独自にローテーションします。
Q4: ローテーション設定したのにログが大きい
A: 次を確認:
- コンテナを再作成したか(daemon.json は新規のみ)
- 1 行が異常に巨大なログを出していないか(ローテーションはファイルサイズ基準)
Q5: /var/lib/docker/containers/ の古いログは削除できる?
A: ローテーション済みの旧ファイル(例:xxx-json.log.1.gz)は削除可。現在の xxx-json.log は truncate で空にし、rm は避けてください。
注意点まとめ
- daemon.json は新規コンテナのみ——既存は再作成
- 値は引用符必須——
"max-size": "10m" - truncate は安全、rm は危険
- ドライバーによって
docker logsの可否が異なる——syslog は非対応 - daemon.json 変更後は Docker 再起動
- ログ設定は定期確認——新規デプロイの漏れ防止
一言で言えば:先に設定し、定期点検。ディスクがあふれてから慌てない。
結論
記事冒頭の午前 3 時のアラートに戻ります。
その夜は 30 分でログ削除、2 時間でローテーションと監視設定、全コンテナの再作成——朝 6 時までかかりました。
教訓は一つ。Docker ログ管理は軽視できません。普段は見えなくても、爆発すると大事故になります。
要点の整理:
応急時:truncate で巨大ログを空にし、容量を確保してサービス復旧。
予防時:daemon.json でローテーション(max-size + max-file)、local または json-file を選択し、全コンテナを再作成して反映。
長期運用:ディスク監視アラート、ログ設定の定期確認、アプリ側のログ出力最適化。
Docker を使っているなら、今すぐ確認を:
find /var/lib/docker/ -name "*.log" -exec ls -sh {} \; | sort -h -r | head -10で巨大ログの有無/etc/docker/daemon.jsonにローテーション設定があるかdocker inspectで全コンテナにログ制限が効いているか
深夜のアラートで目が覚める前に、済ませておきましょう。
役に立ったら、同じ落とし穴に落ちそうな仲間にも共有してください。少しでも多く眠れる時間を。
次に読む
Docker ログ削除の完全フロー
json.log でディスクがあふれない 5 つの方法:json.log の削除、ログローテーションの設定、ログドライバーの選択
⏱️ 目安時間: 30 分
- 1
ステップ1: 問題の深刻さと応急削除を理解する
問題の深刻さ:
• 本番サーバーのディスク使用率が 100% になり、すべてのサービスが応答停止
• 1 つのコンテナの xxx-json.log がなんと 82GB
• Docker はデフォルトでログファイルサイズを制限しない
• stdout と stderr の出力はすべて json.log に書き込まれ、ディスクが満杯になるまで増え続ける
応急で巨大ログを削除:
• truncate でログを空にする:
truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
• またはログファイルを削除してコンテナを再起動し、すぐにディスク容量を確保 - 2
ステップ2: ログローテーションを設定しサイズを制限する
ログローテーションの設定:
• daemon.json で log-opts を設定(max-size: 10m、max-file: 3)
• 1 ファイルあたりの最大サイズと保持ファイル数を制限
• ログを自動ローテーションし、無限増殖を防ぐ
設定例:
• /etc/docker/daemon.json に追加:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
• Docker を再起動:systemctl restart docker
サイズ制限:
• max-size で 1 ファイルの上限(10m、50m など)
• max-file で保持世代数(3、5 など)
• 上限超過時は古いログを自動削除 - 3
ステップ3: ログドライバーを選びベストプラクティスを適用する
ログドライバーの選択:
• json-file(デフォルト、開発向け)
• syslog(本番向け、集中管理)
• journald(systemd 環境向け)
• none(ログ無効)
• シーンに応じて適切なドライバーを選ぶ
ベストプラクティス:
• ログローテーションを設定しサイズを制限
• 適切なログドライバーを使う
• 古いログを定期削除:docker system prune
• ディスク使用率を監視しアラートを設定
• ログ設定を定期確認し、新規デプロイのコンテナ漏れを防ぐ
一言で言えば:先に設定し、定期点検。ディスクがあふれてから慌てない。
FAQ
なぜ Docker のログファイルはディスクを食いつぶすのか?
• 本番サーバーのディスク使用率が 100% になり、すべてのサービスが応答停止
• 1 つのコンテナの xxx-json.log がなんと 82GB
• Docker はデフォルトでログファイルサイズを制限しない
• stdout と stderr の出力はすべて json.log に書き込まれる
• ディスクが満杯になるまで増え続ける
ログの場所:/var/lib/docker/containers/<container-id>/<container-id>-json.log。各コンテナのログはここに保存され、ローテーション未設定だと無限に肥大化します。
Docker ログを応急削除するには?
• truncate でログを空にする:
truncate -s 0 /var/lib/docker/containers/<container-id>/<container-id>-json.log
• またはログを削除してコンテナを再起動し、すぐに容量を確保
巨大ログを探す:
• find で大きいファイルを検索:
find /var/lib/docker/containers -name '*-json.log' -size +1G
• du でディレクトリサイズを確認:
du -sh /var/lib/docker/containers/*
• 容量を食っているログを特定
Docker のログローテーションはどう設定する?
• daemon.json の log-opts(max-size: 10m、max-file: 3)
• 1 ファイルの上限と保持数を制限
• 自動ローテーションで無限増殖を防ぐ
設定例:
• /etc/docker/daemon.json に追加:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
• Docker 再起動:systemctl restart docker
サイズ制限:
• max-size で 1 ファイル上限(10m、50m など)
• max-file で保持世代(3、5 など)
• 超過分は古いログを自動削除
Docker ログ削除のベストプラクティスは?
• ログローテーションでサイズを制限
• 適切なログドライバーを使う
• 古いログを定期削除:docker system prune
• ディスク使用率を監視しアラート設定
• ログ設定を定期確認し、新規デプロイ漏れを防ぐ
一言で言えば:先に設定し、定期点検。ディスクがあふれてから慌てない。docker inspect で全コンテナにログ制限が効いているか確認し、深夜のアラートで気づく前に対策を。
6分で読めます · 公開日: 2025年12月18日 · 更新日: 2026年6月8日
Docker 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
docker logs コマンド詳解:コンテナ障害を素早く特定する7つのテクニック
docker logs の7つの実用テクニックを解説。リアルタイム表示、直近N行、時間フィルター、grep 検索、ログファイルの場所、整形出力、本番環境のベストプラクティスでコンテナ障害を素早く切り分けます。
第 33 / 37 記事
次の記事
Docker コンテナデバッグガイド:exec で内部に入って問題を特定する正しい方法
docker exec でコンテナに入ってデバッグする正しい方法を解説。exec と attach の違い、ツールのインストール、ユーザー権限の指定など実践シーンを網羅し、コマンド例付きでコンテナ問題の切り分けを支援します。
第 35 / 37 記事
関連記事
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker インストールの落とし穴ガイド 2025:permission denied から正常起動までの完全解決策
コメント
GitHubアカウントでログインしてコメントできます