C 盘告急:Docker 的虚拟磁盘里我抠回了 20GB
现象
200GB 的 C 盘只剩 13.7GB。代码、模型、项目全在 F 盘,按理不该爆。一层层查下去,大头是:
docker_data.vhdx40.5GB(C:\Users\<你>\AppData\Local\Docker\wsl\disk\)- uv 缓存 6.65GB
Docker 的逻辑盘和构建缓存默认全写 C 盘 vhdx——哪怕你所有项目都在别的盘。
第一轮:清逻辑垃圾
docker system df # 先看占用构成,我这儿 54.6GB
docker rm <停摆13天的容器> # 确认本地有替代运行方式再删
docker rmi <无用镜像>
docker builder prune -a # 这一步最狠:光 build cache 就 16.4GB
docker image prune
system df 从 54.6GB 降到 8.2GB。但 vhdx 文件还是 40.5GB,一字节没少。
原因:WSL2 的动态扩展虚拟盘只增不缩——Docker 里删掉的空间是逻辑释放,物理文件不会自动回吐。
第二轮:物理压实
docker desktop stop
wsl --shutdown
diskpart
select vdisk file="C:\Users\<你>\AppData\Local\Docker\wsl\disk\docker_data.vhdx"
compact vdisk
exit
docker desktop start
5-10 分钟。结果:vhdx 40.5GB → 20.8GB,C 盘自由空间 13.7GB → 33.5GB。Docker Desktop 配的容器 restart 策略把服务自动拉回来了,没受影响。
实际回收比 54.6→8.2 的逻辑差值少一截——ext4 分配、元数据、overlay 层余量占了一些,vhdx 没法 100% 贴到逻辑用量。想再挤可以做 wsl 内 fstrim,收益不大。
三个别踩的坑
- 别把 vhdx 搬去 U 盘。 随机 IO 慢不说,运行中途拔盘 = 直接损坏。搬家不如压实。
- uv / npm 缓存被常驻进程锁着时别 —force 硬删。 我的 uv 缓存被在跑的 MCP 服务进程锁住,清理超时——正确姿势是重启机器后再
uv cache clean,别伤运行中的服务。 - prune 后 docker daemon 可能假死一两分钟(端口全 000),别慌着杀进程,等它自己恢复,容器数据无损。
顺手体检清单
docker system df看虚胖程度,build cache 占一半以上就值得动手- 停摆超过两周的容器先确认它服务的功能有没有别的方式在跑(我这边容器版早被本地 venv 替代了)
- 大镜像删之前想想重建成本:ollama 那种 9.9GB 且根本没人用的(我的 embedding 走的本地 node-llama-cpp,和它无关),删
- Windows 以管理员跑的 shell:diskpart 直接干,不用另开提权窗口
一句话:Docker for Windows 的空间管理 = 逻辑清理 + 物理压实两步,少一步等于白干。