目次

Docker のディスク使用量を削減する方法(prune コマンド)

Docker をしばらく使っていると、古いイメージ、停止したコンテナ、ビルドキャッシュ、使われていない Volume が次々に蓄積し、数十 GB を占めることもあります。この節では、まず容量を使っている対象を特定し、安全に整理します。すべての出力は、同じ環境で順番に実行した結果です。

まず使用量を確認する

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          13        3         2.886GB   2.377GB (82%)
Containers      4         1         98.3kB    16.38kB (16%)
Local Volumes   4         1         40.61MB   40.61MB (100%)
Build Cache     151       0         3.554GB   2.954GB
項目意味
TOTAL合計数
ACTIVEコンテナが使用中の数
SIZE使用している容量
RECLAIMABLE回収できる容量(未使用分)

この環境には 13 個のイメージがあり、使用中なのは 3 個だけです。2.377 GB(82%)を回収できます。ビルドキャッシュはさらに大きく、2.954 GB あります。-v を付けると、各イメージ、コンテナ、Volume の詳細を確認できます:docker system df -v。

現在のイメージとコンテナ:

$ docker images
IMAGE               ID             DISK USAGE   CONTENT SIZE   EXTRA
adminer:latest      74f29c416e14        164MB         43.8MB
alpine:3.23         85fe1e81d675       26.6MB         8.21MB   U
hello-node:latest   4063457524bb        245MB         62.2MB
myapp:latest        80cb5c41a286       54.9MB         24.8MB   U
mysql:8.4           24989179f588       1.12GB          254MB
nginx:1.30          9bf97bd7714f        242MB         66.5MB
nginx:1.30-alpine   0985e772fb9f       93.7MB           27MB   U
node:24-alpine      ebfe2f904627        242MB           62MB
postgres:18         74935e722416        650MB          169MB
python:3.14-slim    a2b82f3c4855        180MB         45.7MB
redis:8-alpine      3811787313eb        161MB         39.6MB
registry:3          ddf754342cfc       86.9MB         20.7MB
ubuntu:26.04        f144425ff09b        162MB         45.6MB
$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                  CREATED         STATUS                     PORTS     NAMES
cc43746c9a29   alpine:3.23         "true"                   7 seconds ago   Exited (0) 6 seconds ago             anon1
7e269fff858b   nginx:1.30-alpine   "/docker-entrypoint.…"   8 seconds ago   Up 7 seconds               80/tcp    web
bf5ff318eb63   alpine:3.23         "echo done"              8 seconds ago   Exited (0) 7 seconds ago             old2
b580380c1fd2   myapp               "cat /version.txt"       9 seconds ago   Exited (0) 8 seconds ago             old1

EXTRA 欄の U は In Use(コンテナが使用中)を表します。コンテナのうち、実行中なのは web だけです。残りの 3 個は終了済み(Exited)ですが、まだ容量を使用しています。

項目ごとに整理する

コマンド削除される対象
docker container prune停止中のすべてのコンテナ
docker image pruneダングリングイメージ(名前のない <none>)
docker image prune -aどのコンテナからも使用されていないすべてのイメージ
docker builder pruneビルドキャッシュ
docker volume prune未使用の匿名 Volume
docker volume prune -a未使用のすべての Volume(名前付きも含む)
docker network prune未使用のカスタムネットワーク

各コマンドは実行前に確認を求めます(Are you sure you want to continue? [y/N])。-f を付けると確認を省略でき、スクリプトに適しています。以下の例ではすべて -f を付けています。

停止中のコンテナを削除する

$ docker container prune -f
Deleted Containers:
cc43746c9a2993bda0fb21ab3f161b78603353714f396f86fa8c4b5caf90e25a
bf5ff318eb6331a05239ad7fa39420ff96dc1c8f84b9a3548ce38a0f71a2d63a
b580380c1fd2dc6cca2dc6e009bb877c3eb2df1cf388664a32c8932aff8169fa

Total reclaimed space: 16.38kB

停止中の 3 個のコンテナが削除されました。実行中の web には影響しません。

Docker Desktop を使っている場合は、Containers 画面でコンテナにチェックを入れて Delete をクリックしても削除できます。

Docker Desktop の Containers 画面でコンテナにチェックを入れて Delete をクリック
Docker Desktop:コンテナにチェックを入れて Delete をクリックします。画像出典:Docker 公式ドキュメント(Apache-2.0)

Docker 29:再ビルドしても <none> イメージが残らない

以前は、同じ名前でイメージを再ビルドすると(たとえば docker build -t myapp . を複数回実行すると)、古いバージョンは <none> という名前の「ダングリングイメージ」になり、docker image prune で整理する必要がありました。Docker 29 で実測します。

$ docker build -q --build-arg VERSION=4 -t myapp:latest .
sha256:3f33bc33eb36171280e9b90d904e25c58b2dcf509390536580ffacafc35d4595

$ docker images --filter dangling=true
IMAGE   ID             DISK USAGE   CONTENT SIZE   EXTRA

$ docker ps -a --filter name=old1
CONTAINER ID   IMAGE          COMMAND              CREATED          STATUS                      PORTS     NAMES
b580380c1fd2   80cb5c41a286   "cat /version.txt"   26 seconds ago   Exited (0) 26 seconds ago             old1

myapp:latest を連続して 4 回ビルドしましたが、--filter dangling=true の結果は空です。Docker 29 はデフォルトで containerd イメージストレージを使用するため、新しいイメージに名前が置き換わると、古いバージョンは <none> として残りません。古いバージョンを使っているコンテナ(old1)では、IMAGE 欄にイメージ ID が表示されます。

そのため、Docker 29 では docker image prune(-a なし)で削除できるものは通常ほとんどありません。容量を占めるのは、未使用でも名前が付いているイメージとビルドキャッシュです。

匿名 Volume を削除する

$ docker volume ls
DRIVER    VOLUME NAME
local     6f6f8ce590c609d4f39b3a676282da88866c8ab20a064132f7746c3cf6717f2c
local     991c93cb6ebeac8570e9c15a89b4225c2bb5e20cbfde2f5bf665fa4dfa23a1aa
local     5396795eeeaab8415295814207a02f75f6ea136d5c34574ba9b16ecdc1b975f9
local     cleanup-demo_pgdata

$ docker volume prune -f
Deleted Volumes:
5396795eeeaab8415295814207a02f75f6ea136d5c34574ba9b16ecdc1b975f9
991c93cb6ebeac8570e9c15a89b4225c2bb5e20cbfde2f5bf665fa4dfa23a1aa
6f6f8ce590c609d4f39b3a676282da88866c8ab20a064132f7746c3cf6717f2c

Total reclaimed space: 0B

$ docker volume ls
DRIVER    VOLUME NAME
local     cleanup-demo_pgdata
  • 先頭の3つの長い名前は匿名 Volumeです。たとえば、postgres イメージの Dockerfile で VOLUME が宣言されていると、実行時にマウントしなくても Docker が匿名 Volume を自動的に作成し、コンテナを削除した後も残ります(Volume とデータの保持を参照)。
  • docker volume prune は未使用の匿名 Volumeだけを削除します。
  • cleanup-demo_pgdata は Compose プロジェクトの名前付き Volume です。docker compose down の後は使用中のコンテナがありませんが、削除されません。

ビルドキャッシュを削除する

$ docker builder du | tail -n 3
Private:	2.996GB
Reclaimable:	3.596GB
Total:		3.596GB

$ docker builder prune -f --filter until=1h | tail -n 3
lv85kuv5xx5h65k941qjoxecz               	true 	98.69kB   	About an hour ago
kc9tcgw8l1aq9dz1agx096se0               	true 	870kB     	About an hour ago
Total:	1.662GB

$ docker builder prune -f | tail -n 3
6os07ml167zpcfh09ushitk2b               	true 	8.285kB   	38 minutes ago
7ir7u28j6esk2x7pyu6q38kvk               	true 	74.75MB   	38 minutes ago
Total:	1.334GB
  • docker builder du はビルドキャッシュの合計が 3.596 GB で、すべて回収可能であることを示します。
  • --filter until=1h は1時間以上使われていないキャッシュだけを削除し、1.662 GB を回収しました。
  • フィルターを指定しない場合は、さらに 1.334 GB を回収します。

ビルドキャッシュを削除すると、次回のビルドですべての手順(たとえば npm ci や pip install)を再実行するため、時間がかかります。ただし、イメージやコンテナには影響しません。

docker system prune で一括クリーンアップ

docker system prune

停止中のコンテナ、未使用のネットワーク、宙ぶらりんのイメージ、ビルドキャッシュが削除されます。

docker system prune -a

さらに、使用されていないすべてのイメージも削除されるため、次回使用するときに再ダウンロードが必要です。

実測:--volumes でデータベースのデータは削除される?

多くのチュートリアル(このチュートリアルの旧版を含む)では、docker system prune --volumes を実行すると、docker compose down の後に「一時的に使われていない」データベースの Volume も削除されると警告しています。Docker 29 で実測しました。

$ docker system prune --volumes -f
Deleted Containers:
871f1c408d23dd413804105498b5520385dfafc9e558c02447ed940684bbc483

Deleted Volumes:
e5d0caa972c5323d5a64e9baf5fcb21d66ce7fbb4879bdcc7aa068a14fdbbf76

Total reclaimed space: 8.192kB

$ docker volume ls
DRIVER    VOLUME NAME
local     cleanup-demo_pgdata

--volumes で削除されたのは匿名 Volume 1つだけで、Compose データベースの名前付き Volume cleanup-demo_pgdata は残っています。Docker 23 以降では、volume prune と system prune --volumes はデフォルトで匿名 Volume だけを対象にします。

名前付き Volume を削除するには、docker volume prune -a を使います。

$ docker volume prune -a -f
Deleted Volumes:
cleanup-demo_pgdata

Total reclaimed space: 40.61MB

$ docker volume ls
DRIVER    VOLUME NAME

今回は cleanup-demo_pgdata が削除され、中にあった 40.61 MB のデータベースファイルも一緒に消えました。復元できません。

データが一切不要だと確認できた場合に限り、docker volume prune -a を使ってください。特定の Volume を削除するには、docker volume rm 名前 のほうが安全です。Compose プロジェクトでは docker compose down -v を使うと、そのプロジェクトの Volume だけが削除されます。Docker 20.10 以前を使っている場合は、--volumes で名前付き Volume も削除されます。

未使用のイメージをすべて削除する

$ docker image prune -a -f | grep -E "^untagged|^Total"
untagged: nginx:1.30
untagged: node:24-alpine
untagged: postgres:18
untagged: python:3.14-slim
untagged: myapp:latest
untagged: mysql:8.4
untagged: redis:8-alpine
untagged: registry:3
untagged: ubuntu:26.04
untagged: adminer:latest
untagged: alpine:3.23
untagged: hello-node:latest
Total reclaimed space: 2.665GB

$ docker images
IMAGE               ID             DISK USAGE   CONTENT SIZE   EXTRA
nginx:1.30-alpine   0985e772fb9f       93.7MB           27MB   U

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          1         1         93.66MB   0B (0%)
Containers      1         1         81.92kB   0B (0%)
Local Volumes   0         0         0B        0B
Build Cache     26        0         599.6MB   506.9MB
  • web コンテナで使用中の nginx:1.30-alpine を除き、ほかの12個のイメージが削除され、2.665 GB を回収しました。
  • 最後の docker system df の結果では、イメージは 93.66 MB だけ残っています。

これらのイメージは、次回 docker run やビルドで使うときに自動的に再ダウンロードされます。ネットワークが遅い場合や、イメージが非常に大きい場合(たとえば AI モデル関連のイメージは数 GB になることがあります)は、--filter を使って古いものだけを削除することを検討してください。

docker image prune -a --filter "until=168h"      # 7日より前に作成されたものだけを削除

until が照合するのはイメージの作成時刻(イメージの作成者がビルドした時刻)であり、ダウンロードした時刻ではありません。

コンテナのログも容量を消費する

デフォルトの json-file ログにはサイズ上限がありません。出力を続けるコンテナ(yes コマンドで毎秒大量のテキストを出力)を実測しました。

$ docker run -d --name noisy alpine:3.23 sh -c "timeout 3 yes hello-docker-log; sleep 600"
863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6

$ docker inspect --format "{{.LogPath}}" noisy
/var/lib/docker/containers/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6-json.log

$ du -h $(docker inspect --format "{{.LogPath}}" noisy)
69.3M	/var/lib/docker/containers/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6/863ccacbc4bcf86a81cc3bf7603cef1d6ecc004553ac4b36dd7ef52172ed3dc6-json.log

$ docker rm -f noisy
noisy

3秒間出力しただけで、ログファイルは 69.3 MB になりました。長時間実行され、ログが多いコンテナでは、ログファイルが数十 GB に達することがあり、コンテナを削除するまで自動では削除されません。ログファイルは /var/lib/docker/containers/コンテナID/ にあります。Linux ホストでは、次のようにして最大のログファイルを見つけられます。

sudo du -h /var/lib/docker/containers/*/*-json.log | sort -h | tail

コンテナ単位でログの上限を設定する

$ docker run -d --name noisy --log-opt max-size=10m --log-opt max-file=3 alpine:3.23 sh -c "timeout 3 yes hello-docker-log; sleep 600"
fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161

$ ls -lh $(dirname $(docker inspect --format "{{.LogPath}}" noisy)) | grep json
-rw-------    1 root     root        3.2K Oct 13 01:07 config.v2.json
-rw-r-----    1 root     root        7.2M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log
-rw-r-----    1 root     root        9.5M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log.1
-rw-r-----    1 root     root        9.5M Oct 13 01:07 fab1c34ceecb955dc33c01f0e7aa0a60b4137e68d0fe465d52ce23b49ba66161-json.log.2
-rw-------    1 root     root        1.5K Oct 13 01:07 hostconfig.json

$ docker inspect --format '{{json .HostConfig.LogConfig}}' noisy
{"Type":"json-file","Config":{"max-file":"3","max-size":"10m"}}

$ docker rm -f noisy
noisy

max-size=10m は各ファイルの最大サイズが 10 MB、max-file=3 は保持するファイル数が最大 3 つという意味です。古いファイルは .1、.2 にローテーションされます。同じ量の出力でも、ログの合計サイズは約 26 MBに収まり、その後も増えません。

Compose では次のように記述します。

services:
  app:
    image: myapp
    logging:
      options:
        max-size: "10m"
        max-file: "3"

ログの上限をグローバルに設定する

新しいすべてのコンテナに上限を適用するには、Linux では /etc/docker/daemon.json を編集し、Docker Desktop では Settings → Docker Engine で同じ JSON を編集します。

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

Linux では変更後に sudo systemctl restart docker を実行し、Docker Desktop では Apply & restart をクリックします。設定が適用されるのはその後に新しく作成したコンテナだけです。既存のコンテナには削除して再作成する必要があります(Compose では docker compose up -d --force-recreate を実行します)。

Docker Desktop:クリーンアップ後もディスク空き容量が増えない

Windows と macOS では、Docker のデータはすべて仮想ディスクファイルに保存されます。イメージを削除すると仮想ディスク内の領域は解放されますが、ファイル自体はすぐに小さくなるとは限りません。

  • Docker Desktop:Settings → Resources → Advanced で仮想ディスクの上限を確認・調整できます。Troubleshoot 画面の Clean / Purge data を実行すると Docker のデータ(イメージ、コンテナ、Volume)がすべて削除されるため、最後の手段としてのみ使用してください。
  • Windows(WSL 2):.vhdx ファイルがまだ大きい場合は、まず wsl --shutdown を実行してから、diskpart の compact vdisk を使って該当する .vhdx ファイルを圧縮できます。

定期的なクリーンアップのおすすめ

サーバーでは cron を使って、週に 1 回実行できます。

docker container prune -f --filter "until=168h"
docker image prune -af --filter "until=168h"
docker builder prune -af --filter "until=168h"

この一連のコマンドは Volume に一切触れないため、データベースのデータは安全です。グローバルなログ上限も設定すれば、ディスク容量が制御できなくなるのを防げます。

まとめ

  • まず docker system df で確認してから、削除するものを決めます。
  • image prune -a は未使用のイメージをすべて削除し、builder prune はビルドキャッシュを削除します。
  • volume prune が削除するのは匿名 Volume だけです。名前付き Volume も対象にするには -a を指定します。
  • max-size と max-file でログの上限を設定します。

練習問題

練習 1:cron に登録でき、どの Volume にも触れずに、7 日以上前のイメージとビルドキャッシュだけを削除するコマンドを書いてください。

解答
docker image prune -af --filter "until=168h"
docker builder prune -af --filter "until=168h"

よくある質問

docker system prune は安全ですか?

--volumes を付けなければ、Volume は一切変更されません。Docker 23 以降は --volumes を付けても匿名 Volume だけが削除されます。本当に危険なのは docker volume prune -a です。

整理しても Windows のディスク空き容量が増えませんか?

Docker Desktop のデータは仮想ディスクファイルに保存されるため、イメージを削除してもファイルサイズがすぐに縮小するとは限りません。詳しくはこの章の最後の節を参照してください。

ビルドキャッシュをすべて削除できますか?

できます。イメージやコンテナには影響しませんが、次回のビルドに時間がかかります。

更新日 2026年10月14日