【Linux】WSL 中 Docker 占用大量磁盘空间但无法释放的完整解决记录

我遇到的问题

在 WSL(Ubuntu 22.04.5 LTS)中执行:

1
docker system prune -a

清理日志显示释放了 约 81 GB 的 Docker 数据(镜像层、构建缓存、dangling layers、无用容器等)。

但问题是:

  • 打开 Windows 资源管理器查看 C 盘空间发现:空间完全没有增加
  • 也就是说:Docker 清掉了,但 C 盘没变小
  • 这让我怀疑是不是清理失败了,或是空间被别的东西占用了

发现原因:WSL 的 ext4.vhdx 不会自动缩小

进一步排查后了解到:

WSL2 的所有 Linux 文件(包括 Docker 数据)都存储在一个虚拟硬盘文件中:

1
2
C:\Users\<YOUR>\AppData\Local\Packages\
CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx

这个 .vhdx 文件具有以下特点:

  • 会随着写入数据不断增大
  • 不会随着删除数据自动变小
  • 即使 WSL 内部释放了空间,VHDX 在 Windows 侧仍保持原有大小

因此,虽然 WSL 内部释放了 81 GB,

Windows 主机上占用的磁盘并没有同步减少


解决过程:压缩 ext4.vhdx 使其重新回收空间

要真正释放 C 盘空间,需要手动“压缩” VHDX 文件。
步骤如下:

步骤 1:关闭 WSL

在管理员 PowerShell 中执行:

1
wsl --shutdown

确保虚拟磁盘未被占用,才能压缩。

步骤 2:执行 Optimize-VHD

继续在管理员 PowerShell 执行:

1
Optimize-VHD -Path "C:\Users\<YOUR>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx" -Mode Full

此命令执行了一次完整的 VHDX 空间回收与压缩。

过程可能持续几分钟到几十分钟,根据释放空间的大小不同而有所差异。


最终结果

执行完 Optimize-VHD 后:

  • ext4.vhdx 的文件大小 减少了约 100 GB
  • Windows C 盘可用空间明显增加
  • WSL + Docker 占用的虚拟磁盘终于缩小了,清理效果可见

清理前后差异非常明显,说明压缩成功且效果显著。


总结

  1. Docker 清理不等于释放 Windows 磁盘空间
    WSL2 的文件系统都存放在 ext4.vhdx 中,删除文件不会让 VHDX 自动变小。

  2. Docker 占用大量空间是常见情况
    尤其是 build cache、镜像层等,经常导致 VHDX 超过百 GB。

  3. 真正释放空间必须压缩 VHDX 文件
    使用 Optimize-VHD(Windows 专业版)或其他工具(如 wslcompact)才能让体积缩小。

  4. 日常 Docker 使用建议定期压缩 VHDX
    特别是在频繁构建镜像的开发环境中。