目次
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 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日