docker system pruneでディスク容量を管理する方法|overlay2肥大の原因調査と安全な削除手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Docker > docker system pruneでディスク容量を管理する方法|overlay2肥大の原因調査と安全な削除手順
「df -hで/var/lib/dockerが80%を超えた」「docker psで稼働中のコンテナはほとんどないのに、ディスクが膨らみ続けている」

Dockerを運用していると、こういった状況に必ずぶつかります。原因のほとんどは、停止済みコンテナ・dangling image(タグのない中間イメージ)・未使用ボリュームが/var/lib/docker/overlay2に蓄積していることです。

この記事では、docker system dfで現状を正確に把握してから、docker system pruneの各オプション(--all・--volumes・--filter)を使い分けて段階的に削除する手順を解説します。Ubuntu 24.04 LTS / RHEL 9.4の実機出力を交えながら、CI/CD環境や本番環境での定期prune設計まで網羅します。

この記事のポイント

・overlay2肥大の原因は停止コンテナ・dangling image・未使用volumeの3つ
・docker system dfで種別ごとの使用量を確認してから削除する
・docker system prune --all --volumesで一括削除できるが本番では段階的に実行する
・--filterで「until=168h」と指定して直近7日以上のリソースのみ削除できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜDockerのoverlay2がディスクを圧迫するのか?

Dockerはコンテナのファイルシステムを「overlay2」ストレージドライバで管理しています。ビルドのたびにイメージレイヤーが/var/lib/docker/overlay2に積み上がり、使わなくなったコンテナやイメージを明示的に削除しない限り、ディスクは増え続けます。

overlay2の肥大化を引き起こす主な原因は次の4つです。

dangling image(タグなし中間イメージ):docker buildを繰り返すたびに発生する。docker images -f dangling=trueで確認できる未参照のイメージレイヤー
停止済みコンテナ(exited container):docker runで起動してdocker stopで停止したコンテナは、明示的にrm/pruneしない限りファイルシステムが残る
未使用ボリューム(unused volume):コンテナを削除してもdocker volume rmしない限りデータボリュームはディスクに残る
未使用ネットワーク(unused network):docker network createで作成したネットワーク定義が残留する

特にCI/CD環境では、ビルドのたびにイメージが積み上がるため、週単位で数十GBになることも珍しくありません。定期的なpruneが必須です。

docker system dfで現状を把握する

削除の前に必ず現状を把握します。docker system dfは、イメージ・コンテナ・ボリューム・ビルドキャッシュの使用量を種別ごとに一覧表示します。

# ディスク使用量を種別ごとに確認する $ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 43 3 12.47GB 11.23GB (90%) Containers 5 2 124MB 98MB (79%) Local Volumes 18 4 8.32GB 6.78GB (81%) Build Cache 127 0 4.56GB 4.56GB (100%)

「RECLAIMABLE」列が回収可能な領域です。上の例では合計26GB超のうち約22GBがpruneで解放できる状態です。

詳細を確認したい場合は-vオプションを付けます。個別のイメージ・コンテナ・ボリュームまで一覧表示されます。

# 詳細表示(イメージごとのサイズを確認する) $ docker system df -v Images space usage: REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS node 18 a3d4e2f8b1c9 3 weeks ago 1.09GB 0B 1.09GB 0 python 3.11 b7c3d9e4f2a1 4 weeks ago 1.01GB 0B 1.01GB 0 <none> <none> d8f4a2b6c3e5 5 weeks ago 892MB 123MB 769MB 0 <none> <none> e5a1c7b4d9f3 6 weeks ago 758MB 123MB 635MB 0 ...

REPOSITORYが「<none>」のエントリがdangling imageです。使われていないのにレイヤーを占有しています。

docker system pruneの各オプションと使い分け

1. 基本的なprune(停止コンテナ・未使用ネットワーク・dangling imageを削除)

オプションなしのdocker system pruneは、以下の4種類を削除します。

・停止済みコンテナ(exitedステータス)
・未使用ネットワーク(コンテナが接続していないもの)
・dangling image(タグなし・未参照のイメージ)
・ビルドキャッシュ

実行前に「削除対象の概要確認画面」が表示され、「y」で実行できます。

# 基本的なpruneを実行する $ docker system prune WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all dangling build cache Are you sure you want to continue? [y/N] y Deleted Containers: c3d8e4f2a1b5 Deleted Images: deleted: sha256:d8f4a2b6c3e5... Total reclaimed space: 4.23GB

確認プロンプトをスキップして自動実行したい場合は-f(--force)オプションを使います。cronで定期実行する際に必要です。

# 確認なしで自動実行する(cronや自動化スクリプト向け) $ docker system prune -f

2. --allオプション(未使用イメージをすべて削除)

オプションなしのpruneはdangling imageのみ削除しますが、--allを付けると「どのコンテナからも参照されていないイメージ」をすべて削除します。

# 未使用イメージをすべて含めて削除する $ docker system prune --all WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all images without at least one container associated to them - all build cache Are you sure you want to continue? [y/N] y Deleted Images: untagged: node:18 deleted: sha256:a3d4e2f8b1c9... untagged: python:3.11 deleted: sha256:b7c3d9e4f2a1... Total reclaimed space: 11.23GB

現在起動中のコンテナが使っているイメージは削除されないため、本番稼働中のサービスを止めずに実行できます。ただし、次回ビルドやコンテナ起動時にイメージをpullし直すので、その分の通信・時間コストが発生します。

3. --volumesオプション(未使用ボリュームも削除)

--volumesを付けると、どのコンテナからも参照されていないdocker volumeも削除対象に加わります。データベース用のボリュームが残っていた場合、この操作でデータが失われます。本番環境では実行前に必ずバックアップを確認してください。

# 未使用ボリュームも含めて削除する(本番環境は事前確認必須) $ docker system prune --volumes WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all volumes not used by at least one container - all build cache Are you sure you want to continue? [y/N] y Deleted Volumes: my-app-data_postgres_data my-app-data_redis_data Total reclaimed space: 6.78GB

4. --filterオプション(削除対象を絞り込む)

--filterで削除対象を絞り込めます。特に便利なのがuntilフィルターで、指定時間より古いリソースのみを削除できます。

# 7日(168時間)より古いリソースのみ削除する $ docker system prune --all --filter "until=168h" # 特定のラベルが付いたリソースのみ削除する $ docker system prune --filter "label=env=staging" # ラベルがないリソースを除外する(本番コンテナを守る) $ docker system prune --filter "label!=env=production"

until=168hは「168時間=7日以上前に作成されたリソース」を対象にします。直近のイメージやコンテナは残るため、本番環境での定期クリーンアップに適しています。

安全な削除の実行手順(段階的アプローチ)

一気にdocker system prune --all --volumesを実行するのではなく、段階的に実行するのが安全です。特に本番環境では、各ステップで削除結果を確認しながら進めます。

1. 現状確認

# まずディスク使用量の全体像を把握する $ docker system df # 停止済みコンテナを確認する $ docker ps -a --filter "status=exited" # dangling imageを確認する $ docker images -f dangling=true # 未使用ボリュームを確認する $ docker volume ls -f dangling=true

2. 停止コンテナとdangling imageを削除する

# 最もリスクの低い削除から始める(ボリュームは含まない) $ docker system prune -f # 削除後に再度確認する $ docker system df

3. 未使用イメージを削除する(状況に応じて)

# 直近7日以上使われていないイメージを削除する(--allオプション追加) $ docker system prune --all --filter "until=168h" -f # 回収できた容量を確認する $ df -h /var/lib/docker Filesystem Size Used Avail Use% Mounted on /dev/sda1 80G 23G 57G 29% /

4. 未使用ボリュームの削除は最後に確認してから実施する

# 削除前に対象ボリュームを必ず目視確認する $ docker volume ls -f dangling=true DRIVER VOLUME NAME local old-postgres-data-2024 local staging-redis-backup-0501 # 問題がなければ削除する $ docker volume prune -f Total reclaimed space: 6.78GB

ボリュームの削除は種別ごとのdocker volume pruneでも実行できます。docker system prune --volumesと同じ効果ですが、コンテナ・イメージ・ネットワークは触らずにボリュームだけを削除したい場合に便利です。

CI/CD環境と本番環境での定期prune設計

1. CI/CD環境(GitLab CI・GitHub Actions セルフホストランナー)

ビルドランナーのホストは特に容量が増えやすい環境です。夜間に定期pruneを実行するcron設定が実用的です。

# /etc/cron.d/docker-prune に以下を記述する # 毎日深夜2時にdangling imageとビルドキャッシュを削除する 0 2 * * * root docker system prune -f | tee -a /var/log/docker-prune.log # 週次(日曜深夜3時)に7日以上古いイメージも削除する 0 3 * * 0 root docker system prune --all --filter "until=168h" -f | tee -a /var/log/docker-prune.log

cronのログは/var/log/docker-prune.logに書き出して、翌日に削除量を確認できるようにしておきます。

2. 本番環境(長期稼働コンテナが存在するサーバー)

本番環境では--all--volumesを組み合わせたブランケット削除は避けます。代わりに--filter untilで古いリソースのみを対象にします。

# 本番環境向け:30日(720時間)以上古いリソースのみ削除する 0 4 * * 0 root docker system prune --all --filter "until=720h" -f | tee -a /var/log/docker-prune.log

本番環境でボリュームを削除する場合は、必ず事前にdocker volume ls -f dangling=trueで対象を確認し、バックアップが取れていることを確認してから手動で実行するのが原則です。cronによる自動削除にボリュームを含めることは推奨しません。

3. pruneログを活用したディスク監視

定期pruneのログを確認することで、削除量のトレンドを把握できます。「毎週5GB以上削除されている」状況であれば、ビルドキャッシュの設計(BuildKitのキャッシュ制限など)を見直すサインです。

# 過去1週間のprune実行結果と回収量を確認する $ grep "Total reclaimed" /var/log/docker-prune.log | tail -7 Total reclaimed space: 4.23GB Total reclaimed space: 3.87GB Total reclaimed space: 5.12GB Total reclaimed space: 2.94GB Total reclaimed space: 4.56GB Total reclaimed space: 3.21GB Total reclaimed space: 4.78GB

トラブルシュート:pruneしても容量が減らない時の対処法

「No space left on device」が出てdocker buildも動かない

ディスクがフルに近い状態ではDockerデーモン自体が不安定になることがあります。まずOSレベルで空きを作ります。

# /var/lib/dockerの使用量をディレクトリ別に確認する $ sudo du -sh /var/lib/docker/*/ 4.5G /var/lib/docker/buildkit/ 18.2G /var/lib/docker/overlay2/ 1.2G /var/lib/docker/volumes/

overlay2が特に大きい場合は、すでに削除したはずのコンテナのレイヤーが残存している可能性があります。docker system prune --allを実行してから再確認してください。

pruneしたのにoverlay2が減らない

Linuxのファイルシステムは、ファイルを削除してもそのファイルを開いているプロセスがいる限りディスク領域を解放しません。docker stopせずにコンテナが書き込み続けている場合、pruneしても容量が戻りません。

# 削除済みファイルを開いているプロセスを確認する $ sudo lsof | grep deleted | grep docker | head -10 dockerd 1234 root 23u REG 8,1 2147483648 123456 /var/lib/docker/overlay2/... (deleted) # 該当コンテナを停止・削除してからpruneを再実行する $ docker stop <コンテナID> $ docker rm <コンテナID> $ docker system prune -f

ビルドキャッシュが大量に残っている

BuildKit(Docker 23.0以降のデフォルトビルドエンジン)のキャッシュはdocker system pruneでは削除されないことがあります。docker buildx pruneで明示的にクリアします。

# BuildKitキャッシュを確認する $ docker buildx du ID RECLAIMABLE SIZE LAST ACCESSED hbtul9d5yb3rvs73gafmqxe5u* true 4.52GB 27 hours ago # BuildKitキャッシュを全削除する $ docker buildx prune --all -f Total reclaimed space: 4.52GB

本記事のまとめ

docker system pruneの使い方の早見表です。
やりたいこと コマンド
ディスク使用量を種別確認する docker system df
停止コンテナ・dangling image・ネットワークを削除する docker system prune -f
未使用イメージをすべて削除する docker system prune --all -f
未使用ボリュームも含めて削除する docker system prune --all --volumes -f
7日以上古いリソースのみ削除する docker system prune --all --filter "until=168h" -f
ボリュームだけを削除する docker volume prune -f
BuildKitキャッシュを削除する docker buildx prune --all -f
ポイントをまとめます。

・まずdocker system dfで種別ごとの使用量を把握してから削除に進む
・最初はオプションなしのpruneから始め、--all・--volumesは段階的に追加する
・本番環境では--filter until=720hで古いリソースに絞り、ボリューム削除は手動確認を徹底する
・CI/CD環境ではcronで定期pruneを設定し、ログで削除量のトレンドを監視する

次に読む記事
Dockerのログ運用設計|loggingドライバとjson-fileローテーションで肥大化を防ぐ方法
Dockerコンテナのリソース制限と監視|--memory・--cpusとdocker statsでホストを守る設計
Linuxでディスクが容量不足になった時の対処手順|原因ファイルの特定から安全な削除まで

docker system pruneを含めたDockerの運用管理スキルを体系的に習得したい方は、Docker実践講座(docker.linuxmaster.jp)をご覧ください。現役エンジニアが現場目線で教えるDockerの基礎から本番運用まで、ハンズオン形式で学べます。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。