Docker のディスク容量不足を解消する:イメージ・ビルドキャッシュ・ログ・ボリュームの整理ガイド

Docker で no space left on device が出た場合の対処法。docker system df によるイメージ・コンテナ・ビルドキャッシュの調査から、ログとマウント先の確認、prune と compose down の削除範囲、ログローテーション、業務データの検証まで解説します。

Docker のディスクがいっぱいになったら、まず docker system df -v でリソースの使用量を調べ、続いてコンテナログとマウント先を確認します。再生成できると確認したビルドキャッシュ、dangling イメージ、不要なコンテナから整理してください。ボリュームは用途とバックアップを個別に確認し、「未使用」という表示だけで削除しないでください。

セルフホストのサービスを数か月運用すると、イメージの各バージョン、ビルドキャッシュ、ログ、業務データが同時に増えることがあります。 一度の prune で処理できるのは一部だけです。削除範囲を不用意に広げると、データベースまで失うおそれがあります。

本記事は主に Linux Docker Engine と Compose V2 を対象としています。 Docker CLI の確認コマンドは通常 Windows PowerShell でも実行できますが、Bash と記載したホスト側のコマンドは、実際に Docker を動かしている Linux ホストで実行してください。 ドキュメントの確認日は 2026 年 10 月 22 日です。本記事の作成にあたり、読者のサーバーでクリーンアップやコンテナの再作成は実行していません。

Docker での Syncthing 構築や Joplin Server のセルフホスト手順から来た場合は、まず各サービスの実際のデータディレクトリを確認し、その後で整理する対象を決めてください。

容量不足のディスクと接続先ホストを特定する

Docker CLI の接続先は、ローカルホスト、リモート SSH context、Docker Desktop の Linux 仮想マシンなどです。 別の context で容量を調べても、対象サーバーとは無関係な数値が表示されることがあります。

1
2
3
4
5
docker context show
docker context ls
docker version
docker info
docker compose version

サーバー側の情報、現在の context、Docker のデータディレクトリを確認します。 Linux のデフォルトは /var/lib/docker であることが多いものの、rootless 構成、独自設定、ストレージバックエンドによって異なる場合があります。 このデフォルトパスを、そのまま削除対象のディレクトリと考えないでください。

Linux ホストでファイルシステムの容量と inode を確認します。

1
2
df -h
df -i

ディスク容量に余裕があっても、小さなファイルが大量にあり inode を使い切ると、no space left on device が発生します。 書き込み先が別ディスクの bind mount であれば、システムディスクだけでなく、そのマウントポイントを確認してください。

Docker Desktop には仮想ディスクという層もあります。 コンテナ内で解放された領域、仮想ディスクの空き容量、ホスト上のディスクイメージの実使用量は、同時に変化するとは限りません。 Windows の C ドライブの使用量がすぐに減らなくても、それだけで Docker の整理が失敗したとは判断できません。 本記事では、すべての Desktop バックエンドに共通する仮想ディスク圧縮コマンドは扱いません。

使用量の詳細から五種類のデータを見分ける

まず読み取り専用の確認を行います。

1
2
3
4
5
docker system df
docker system df -v
docker ps -a --size
docker image ls
docker volume ls

docker system df は Docker リソースの使用量を表示し、-v でイメージ、コンテナ、ローカルボリュームの詳細を展開します。 イメージ間ではレイヤーを共有する場合があるため、各イメージの SIZE を単純に足しても実際の使用量にはなりません。

種類 主な内容 優先する対応
イメージ 現行版、旧版、ビルドの中間生成物 ロールバック用を残し、確認後に dangling イメージを削除
コンテナの書き込み可能レイヤー 永続化されていないアップロードや一時ファイル 破棄または移行できるか確認
ビルドキャッシュ Dockerfile の各ステップの再利用可能な結果 経過時間で整理し、次回ビルドの遅延を許容
ボリュームと bind mount データベース、設定、添付ファイル、モデル アプリ単位で管理し、変更前にバックアップ
コンテナログ 標準出力、標準エラー ログドライバーを確認し、ローテーションを設定

RECLAIMABLE はリソース回収の条件に合う使用量の推定であり、業務上不要であることを意味しません。 旧イメージが唯一のロールバック手段だったり、参照のないボリュームに保管義務のある廃止済みデータベースが残っていたりする場合があります。

docker ps --size の書き込み可能レイヤーのサイズも、マウントしたデータとログの合計サイズではありません。 この数値が小さいのにホストのディスク使用量が急増する場合は、後述するこの二つを調べます。

整理する前にコンテナとデータの対応を確認する

以下では対象コンテナ名を my-app としています。実際の名前に置き換えてください。

1
2
3
docker inspect my-app --format '{{json .Mounts}}'
docker inspect my-app --format '{{json .HostConfig.LogConfig}}'
docker inspect my-app --format '{{.LogPath}}'

Mounts では次の項目を確認します。

  • Type:volume か bind か。
  • Name:Docker が管理するボリューム名。
  • Source:ホスト側のソースパス。
  • Destination:コンテナ内のマウント先。
  • RW:コンテナから書き込めるか。

たとえば、コンテナ内の /data がホストの /srv/my-app/data に対応するなら、その増加はホストとアプリ側で調査する必要があります。 旧イメージを削除しても、この場所の添付ファイルは減りません。

データベースがまだコンテナの書き込み可能レイヤーに保存されている場合は、先にバックアップと永続ストレージへの移行を計画します。 この状態でコンテナを削除するとデータを失う可能性があるため、後述のコンテナ削除には進まないでください。

Compose プロジェクトでは、正しいプロジェクトディレクトリで次も実行します。

1
2
3
docker compose config --quiet
docker compose ps -a
docker compose images

独自の -f、-p、環境ファイルを使う場合は、確認時もその後の操作時も同じ引数を指定します。 プロジェクト名を変えると別のボリューム群が作成され、データが消えたように見える場合があります。

実際のボリューム名、Compose ファイル、イメージのバージョンを記録し、十分な容量がある独立した場所にバックアップを保存します。 データベースが対応する論理バックアップまたは整合性のあるスナップショットを利用してください。稼働中のデータベースディレクトリをそのままアーカイブしても、復元できない場合があります。

イメージとビルドキャッシュ:再生成できるものから整理する

まずビルドキャッシュを評価する

Build Cache が主な占有元なら、業務ボリュームに手を付けるよりキャッシュの整理が適しています。 ただし、次回のビルドでは依存関係の再ダウンロードや再コンパイルが発生し、時間がかかる可能性があります。

1
docker builder prune --filter 'until=168h'

経過時間の条件に合うビルドキャッシュを削除し、対話的な確認は残します。 168h は七日間です。保持期間の例なので、ビルド頻度に合わせて調整してください。 これはプレビューではなく、確認後にキャッシュを実際に削除します。 引数の詳細は docker builder prune を参照してください。

Buildx で複数の builder を使う環境では、現在の builder も確認します。

1
2
docker buildx ls
docker buildx du

docker buildx du は、現在選択している builder のキャッシュ使用量を表示します。 ある builder の大きな使用量を見て、別の builder で何度も削除しても解決しません。 リモートのビルドマシンも個別に確認し、ローカルディスクを共有していると決めつけないでください。

dangling イメージを削除できるか判断する

dangling イメージを一覧表示します。

1
docker image ls --filter dangling=true

これらのビルド生成物が不要だと確認した後に実行します。

1
docker image prune

デフォルトでは dangling イメージを削除します。 -a を付けると、通常のタグがある旧バージョンを含め、どのコンテナからも参照されないイメージに範囲が広がります。 オフラインでの復旧やロールバックに影響するため、毎回付ける省略手段にはしないでください。 詳しい規則は docker image prune を参照してください。

不要と確認したイメージを一つだけ削除するなら、実際のイメージ ID を指定すると範囲を管理しやすくなります。

1
docker image rm IMAGE_ID

参照の競合が出た場合は、そのイメージを使うコンテナを確認し、保持が必要か再判断します。 すぐに強制オプションで警告を回避しないでください。

不要なコンテナは名前を指定して個別に削除する

停止中でも、コンテナ内に重要なファイルが残っていることがあります。 マウントと書き込み可能レイヤーを確認してから削除を判断します。

1
2
3
docker ps -a --filter status=exited --size
docker inspect old-test-container --format '{{json .Mounts}}'
docker diff old-test-container

docker diff はコンテナのファイルシステムの変更を表示します。バックアップではなく、マウント先の確認の代わりにもなりません。 破棄できるテストコンテナだと確認してから、指定した対象を削除します。

1
docker container rm old-test-container

ここでは -f も -v も使っていません。 それでもコンテナの削除では、書き込み可能レイヤーとコンテナログを失います。重要なファイルは事前に取り出してください。 削除の規則は docker container rm で確認できます。

増え続けるログ:キャッシュ整理後も原因を解消する

docker system df に回収可能な領域がほとんどなければ、ログドライバーとパスを確認します。 Docker のデフォルトの json-file ログドライバーには、デフォルトのサイズ上限がありません。エラーの大量出力でディスクを使い続ける場合があります。

1
2
3
4
docker info --format '{{.LoggingDriver}}'
docker inspect my-app --format '{{json .HostConfig.LogConfig}}'
docker inspect my-app --format '{{.LogPath}}'
docker logs --tail 100 my-app

デフォルトドライバーと各コンテナの実際のドライバーは異なる場合があるため、コンテナの LogConfig を基準にします。 LogPath も、ログドライバーや環境によっては直接確認できるファイルパスを返すとは限りません。 設定の挙動は Docker のログドライバードキュメント を参照してください。

Linux では、返された実際のパスのサイズを読み取り専用で確認できます。 以下のパスを、確認したログファイルのパスに置き換えてください。

1
sudo du -h /actual/path/to/container-json.log

Docker が管理するログファイルを直接削除したり切り詰めたりしないでください。 公式ドキュメントでは、これらのファイルは Docker daemon が専用に管理し、外部からの変更がログシステムに干渉する可能性があると説明されています。 データベース接続失敗や権限エラーが繰り返されているなら、先にアプリの問題を直します。ローテーションだけでは不要なログの発生は止まりません。

Compose サービスにログローテーションを設定する

既存サービスのイメージ、ポート、環境変数、データマウントを維持したまま、次の logging 設定を統合します。

1
2
3
4
5
6
7
services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

これは設定の一部であり、単独で起動できる完全な Compose ファイルではありません。 app は実際のサービス名に置き換えてください。 max-size は各ログファイルのローテーション閾値、max-file は保持するファイル数です。詳細は json-file ドキュメント を参照してください。

変更後に構文を確認し、短時間の停止が許容され、データが永続化されてバックアップもある状態で対象サービスを再作成します。

1
2
3
docker compose config --quiet
docker compose up -d --no-deps --force-recreate app
docker compose ps

再作成ではコンテナが置き換わり、書き込み可能レイヤーの内容は自動では保持されません。 匿名ボリュームに依存する場合は、再利用または移行の方法を先に決めてください。 続いて新コンテナの実際の名前を確認し、設定を調べます。

1
2
docker inspect my-app --format '{{json .HostConfig.LogConfig}}'
docker logs --tail 100 my-app

設定を編集して docker compose restart を実行するだけでは、コンテナ作成時に決まったログオプションは更新されません。 古い設定が表示される場合は、サービス名、Compose ファイル、プロジェクト名、実際のコンテナ ID を確認してください。

ローテーションではローカルの過去ログに保持制限がかかります。長期監査が必要な業務では、別途ログを収集・保管してください。 アプリがマウント先に直接書くログにも、アプリ側の設定や専用のローテーションが必要です。Docker の標準出力のローテーションはそれらを管理しません。

ボリューム:「未使用」と「削除可能」は異なる

コンテナから参照されないボリュームを列挙すると、調査対象を見つけやすくなります。

1
2
3
docker volume ls --filter dangling=true
docker volume inspect my-project-data
docker ps -a --filter volume=my-project-data

ボリュームにコンテナの参照がないのは、単に docker compose down を実行したためかもしれません。 コンテナ削除後も、そこにあるデータベースファイルが次回起動に必要な業務データのすべてである可能性があります。 永続化の仕組みは Docker Volumes のドキュメント を参照してください。

実際に処置する前に、四つの質問に答えられることを確認します。

  1. このボリュームはどのアプリの、どの環境に属するか。
  2. アプリは永久に廃止されたのか、後で再作成する予定なのか。
  3. 独立したバックアップがあり、復元方法を検証しているか。
  4. バックアップの保存先も今回の整理で削除されないか。

不要と確認した特定のボリュームだけ、docker volume rm 实际卷名 による削除を検討してください。末尾のプレースホルダーは実際のボリューム名に置き換えます。 本記事では、ボリュームの一括削除を日常的な保守手順にはしません。 データベースのレコード、添付ファイル、モデルが増加原因なら、まずアプリが対応する保持ポリシー、アーカイブ、移行手順を使います。

prune と compose down の削除範囲

コマンドごとの削除範囲を混同しないでください。

コマンドまたはオプション 把握すべき範囲
docker image prune デフォルトは dangling イメージ
docker image prune -a コンテナから参照されないすべてのイメージに拡大
docker system prune 停止中コンテナ、未使用ネットワーク、dangling イメージ、未使用ビルドキャッシュ
docker system prune --volumes 未使用の匿名ボリュームも対象。バックアップ整理の仕組みではない
docker volume prune 現在のデフォルトは未使用の匿名ローカルボリューム。--all で未使用の名前付きボリュームも対象
docker compose down デフォルトではプロジェクトのコンテナとネットワークを削除し、ボリュームは削除しない
docker compose down -v 宣言された名前付きボリュームと付属する匿名ボリュームも削除。external ボリュームは対象外

正確な引数の挙動は、インストール済みバージョンの --help と現行の公式ドキュメントで確認してください。 system prune、volume prune、compose down を参照してください。

一括削除は簡単に取り消せる操作ではありません。 キャッシュは再生成でき、イメージは再取得できる場合がありますが、削除したボリュームの復元には有効なバックアップが必要です。 また、Compose がデフォルトで匿名ボリュームを削除しなくても、次の up で元の匿名ボリュームが自動的に再接続されるとは限りません。 長期運用では、明示的なデータパスまたは名前付きボリュームを使い、対応する設定も保管してください。

空き容量と業務データの読み書きの両方を検証する

リソースの種類ごとに整理後の使用量を確認すると、何が領域を解放したのか判断できます。

1
2
3
4
docker system df -v
docker ps -a --size
docker compose ps
docker compose logs --tail 100

Linux ホストでも再確認します。

1
2
df -h
df -i

コンテナが Up と表示されるだけで復旧と判断してはいけません。 サービスを開き、既存レコードを読み、削除可能なテストレコードを書き込み、データベースまたは同期ディレクトリが元のデータを使っていることを確認します。 ログ設定の変更で再作成したサービスでは、その後のディスク増加も観察し、ローテーションとアプリのエラーが解決したことを確かめてください。

想定より解放量が少ない場合は、症状に応じて調査を続けます。

症状 次に確認する内容
イメージ一覧は大きいが、少ししか解放されない 共有レイヤーと、コンテナに参照され続けるレイヤー
Build Cache が変わらない 現在の context と builder が対象に一致しているか
Docker リソースは小さいのにディスクがいっぱい bind mount のディレクトリ、ログ、その他のホストファイル
Linux がまだ容量不足を報告する 実際の対象ファイルシステム、inode、クォータ、ストレージバックエンド
Desktop 内の空きは増えたがホスト使用量は変わらない プラットフォームごとの仮想ディスク回収機構
コンテナ再作成後に初期設定ページが表示される プロジェクト名、ボリューム名、bind パス、匿名ボリュームの関連付けの変更

最後の症状では、直ちに追加の書き込みを止め、旧ボリュームが残っているか、設定が新ディレクトリを指していないかを確認します。 そのままボリュームを整理すると、まだ回収できる旧データを本当に削除してしまう可能性があります。

整理後にサービスが異常になった場合は、Compose 設定を戻し、永続マウントを確認してから、保持していたイメージで再作成します。 ボリュームを削除済みなら、イメージの再取得では業務データは戻りません。事前検証済みのバックアップ復元手順に従ってください。

継続的な保守を計画する

保守記録には、少なくとも Docker context、リソース使用量、実際のデータディレクトリ、ログドライバー、バックアップ先を含めます。 頻繁にビルドする開発機ではキャッシュを定期的に評価できます。データベースを長期運用するサーバーでは、容量アラート、データベースのバックアップ、復元訓練を優先してください。

強制オプション、広範なイメージ削除、ボリューム削除を含むコマンドを、そのまま定期実行に登録しないでください。 まず一定期間の読み取り専用の統計を取り、増え続けるリソースを特定してから、対応する保持ポリシーを選びます。

別ディスクへのデータ移行は、rsync の差分同期と検証を参照してください。 データベースディレクトリでは、関連する書き込みを停止するか、アプリが対応する整合性のあるバックアップを使う必要があります。ファイルコピーの成功は、データベースの復元可能性を保証しません。