Difyとn8nを実測したあと、VPSのディスクに 13GB のイメージが残りました(Difyの実測記事)。

片付けようと docker system prune を叩きました。79.75MBしか消えませんでした。

「掃除コマンド」は1つではありません。4段階あり、それぞれ触る場所が違います。 段階ごとに dfdocker system df を取って、どこで何が消えるかを測りました。

結論:4段階で消えるものはこれだけ違う

段階コマンド消えたもの回収
1docker system prune停止中のコンテナ79.75MB
2docker image prune -a未使用イメージ13個12.96GB
3docker volume prune匿名ボリューム20個51.45kB
4docker volume prune -a名前付きボリューム3個5.713MB

第1段階だけで止めると、13GBがそのまま残ります。 第3段階で止めると、データが入っているほうが残ります。

測定条件

  • サーバー:さくらのVPS 2Gプラン / Ubuntu 24.04 LTS / Docker 29系
  • 片付ける対象:Difyのイメージ12個(10.6GB)、n8nのイメージ1個(2.47GB)、コンテナ1個、ボリューム23個
  • 稼働中のコンテナ:なし(測定前にすべて停止・削除済み)
  • 開始時:ディスク使用 23,724MB / 空き 71,808MB

掃除を始める前の docker system df です。

TYPE            TOTAL   ACTIVE  SIZE      RECLAIMABLE
Images          13      1       13.59GB   10.84GB (79%)
Containers      1       0       79.75MB   79.75MB (100%)
Local Volumes   23      1       5.764MB   68.32kB (1%)
Build Cache     0       0       0B        0B

第1段階:docker system prune は79.75MBしか消さない

いちばん多く紹介されているコマンドです。

docker system prune -f
Deleted Containers:
0d66d23f8993...
Total reclaimed space: 79.75MB
変化
ディスク使用23,724MB → 23,648MB(−76MB
/var/lib/containerd13G → 13G(変わらず)

13GBのイメージには一切触っていません。

docker system prune が消すのは、停止中のコンテナ・未使用のネットワーク・タグの付いていないイメージ(dangling)・ビルドキャッシュです。タグの付いた未使用イメージは対象外です。

そして「回収できる量」が増える

掃除した直後の docker system df を見てください。

実行前実行後
Images RECLAIMABLE10.84GB (79%)13.32GB (98%)
Local Volumes RECLAIMABLE68.32kB (1%)5.764MB (100%)

掃除したのに、掃除すべき量が増えました。

理由は単純で、コンテナを削除したことで、そのコンテナが使っていたイメージとボリュームが**「未使用」に変わった**からです。

ACTIVE の列が 1 → 0 になっているのがそれです。この数字は「いま何が使われているか」で動くので、掃除の進捗を測る指標には使えません。

第2段階:docker image prune -a で12.96GB

タグ付きの未使用イメージまで消すには -a が要ります。

docker image prune -a -f
untagged: langgenius/dify-api:1.17.0
untagged: langgenius/dify-plugin-daemon:0.6.10-local
untagged: docker.n8n.io/n8nio/n8n:latest
...
Total reclaimed space: 13.59GB
変化
ディスク使用23,648MB → 10,690MB
実際に減った量12,958MB(12.96GB)
空き71,884MB → 84,841MB
/var/lib/containerd13G → 3.2M

ここで初めて13GBが消えます。

申告13.59GB、実測12.96GB

Dockerは「13.59GB回収した」と言いますが、df で見た実際の減少は 12.96GB0.63GBのズレがあります。

Difyの記事では docker images のサイズを単純に足すと約14GBになり、実際のディスク増加は10.6GBでした。どちらも多めに出ます。 レイヤーが共有されている分の数え方によるものと考えられます。

ただし、docker system df(13.59GB)のほうが docker images の合計(14GB)より実測に近いという結果でした。容量を見積もるなら docker system df を使ってください。

第3段階:ボリュームは、両方のコマンドで生き残る

ここが本題です。第2段階まで終えた時点の docker system df がこれです。

Images          0   0   0B      0B
Containers      0   0   0B      0B
Local Volumes   23  0   5.764MB 5.764MB (100%)

イメージもコンテナもゼロ。ボリュームだけ23個そのまま残っています。

docker system prunedocker image prune -a も、ボリュームには一切触りません。

docker volume prune -f
Deleted Volumes:
2d47d733e1f370bc82a287a45663c11dea97f10f363d3e0ab7f038aaa81f54f8
b353974c60397d63681bb4157a97785b2b489cec4659f65bfdb364a6bd8dd138
(… 20個 …)
Total reclaimed space: 51.45kB

20個消えて51.45kB。 残ったのはこの3つです。

n8n_data
docker_dify_agent_local_sandbox_home
docker_dify_agent_local_sandbox_workspace

docker volume prune は、既定では匿名ボリュームしか消しません。2d47d733... のような16進の名前が匿名ボリュームです。コンテナが勝手に作ります。)

第4段階:-a を付けて、ようやく名前付きが消える

docker volume prune -a -f
Deleted Volumes:
docker_dify_agent_local_sandbox_workspace
n8n_data
docker_dify_agent_local_sandbox_home
Total reclaimed space: 5.713MB

3個で5.713MB。

いちばん危ないのは第3段階で止めることです

数字を並べます。

個数容量全体に占める割合
匿名ボリューム20個51.45kB0.9%
名前付きボリューム3個5.713MB99.1%

20個消しても0.9%。3個消したら99.1%。

当然です。名前を付けるのは、残したいデータがあるときだからです。 匿名ボリュームは中身がほとんど空で、名前付きにデータが入っている。

そして docker volume prune は、その名前付きのほうを残します。

容量ではなく、中身の問題です

5.7MBという数字を見て「誤差じゃないか」と思うかもしれません。容量は問題ではありません。

今回残った n8n_data は、n8nの設定データそのものです。n8nは自動化ツールで、外部サービスに接続するためのAPIキーやパスワードを保存します。

つまり、

  • イメージを13GB消して
  • コンテナも消して
  • docker system df が「Images 0 / Containers 0」と表示していても
  • 認証情報が入ったボリュームは、そこに残り続けます

「片付いた」と思って別の用途にサーバーを回す、あるいは解約する。 そのとき、この5.7MBのことは誰も覚えていません。

消す前に、必ず中身を確認してください。

docker volume ls
docker volume inspect <ボリューム名>     # Mountpoint が実体のパス
sudo ls -la /var/lib/docker/volumes/<ボリューム名>/_data

/var/lib/docker を見ても何も分かりません

掃除の各段階で、この2つを測っていました。

掃除前掃除後
/var/lib/docker6.3MB368KB
/var/lib/containerd13G3.2M

Docker 29系はイメージの実体をcontainerdの管理下に置きます。 /var/lib/docker は最初から最後まで数MBしかありません。

「ディスクが減らない」を調べるとき、/var/lib/dockerdu を見ても答えは出ません。 見るべきは docker system df と、df で見たディスク全体です。

(私は前の記事でここを間違えて、訂正を入れました。)

メモリは戻りません

ディスクは片付きましたが、メモリは別です。

イメージ0個・コンテナ0個・ボリューム0個の状態で、上位プロセスがこれです。

python3          70.3MB
python           60.1MB
dockerd          52.6MB   ← 常駐
fwupd            43.7MB
systemd-journal  35.4MB
containerd       31.3MB   ← 常駐

dockerdcontainerd で合計83.9MB(RSS)が居座っています。 動かすものが1つもないのに、です。

システム全体への影響は約49MB(Difyの記事で実測)。Dockerを使わなくなったなら、掃除ではなくアンインストールが要ります。

安全な片付けの順番

# 1. まず何があるか見る(消す前に必ず)
docker system df
docker volume ls
docker ps -a

# 2. 名前付きボリュームの中身を確認する
docker volume inspect <名前>

# 3. コンテナを止めて消す
docker compose down          # または docker rm

# 4. イメージを消す(-a が要る)
docker image prune -a

# 5. ボリュームを消す(本当に消していいと確認してから)
docker volume prune          # 匿名だけ
docker volume prune -a       # 名前付きも。取り返しがつきません

# 6. 結果を確認する
docker system df
df -h /

-a を付けるコマンドは、付けた瞬間に取り返しがつきません。 特に第5段階は、中身を見てからにしてください。

まとめ

  • docker system prune はイメージを消さない。 今回消えたのは79.75MB(停止中コンテナのみ)
  • タグ付きイメージを消すには docker image prune -a ここで12.96GB減った
  • docker system df の RECLAIMABLE は掃除すると増える。 コンテナを消すとイメージが「未使用」に変わるため。進捗の指標にならない
  • 申告13.59GB、実測12.96GB。 docker system df は多めに出るが、docker images の合計よりは正確
  • ボリュームは上記2つのどちらでも消えない
  • docker volume prune は匿名だけ。 匿名20個=51.45kB、名前付き3個=5.713MB。容量の99.1%が残る
  • 残るのは、データが入っているほうです。 n8nなら認証情報が入っています
  • /var/lib/docker を見ても分からない。 Docker 29系の実体は /var/lib/containerd
  • メモリは戻らない。 dockerd + containerd で83.9MB(RSS)が常駐したまま

「ディスクが減らない」という現象の正体は、掃除コマンドが4つあって、それぞれ触る場所が違うというだけのことでした。

そしていちばん大事なのは、最後まで消すことではありません。 第3段階で止まったとき、何が残っているかを知っていることです。