Docker 删除镜像后磁盘空间没有释放?

Docker 删除镜像后磁盘空间没有释放?真正原因和彻底清理方案

在使用 Docker 的过程中,很多人都会遇到一个非常困惑的问题:

明明已经删除了 Docker 镜像,但是电脑磁盘空间一点都没有增加。

例如:

bash 复制代码
docker rmi xxx-image

执行成功。

查看:

bash 复制代码
docker images

发现镜像已经不存在。

但是 Windows 的 C 盘 / E 盘空间:

一点没回来。

很多人第一反应是:

Docker 删除失败了吗?

实际上,大多数情况下并不是。

Docker 删除的是"镜像",但是磁盘占用可能来自:

  • 镜像层(Layers)
  • 构建缓存(Build Cache)
  • 已停止容器
  • 未使用网络
  • Volume 数据
  • Docker Desktop 使用的 WSL2 虚拟磁盘

一、docker images 显示的大小 ≠ 实际磁盘占用

很多人会误解:

bash 复制代码
docker images

看到:

perl 复制代码
REPOSITORY     SIZE
my-app         5GB

于是认为:

删除这个镜像应该释放 5GB。

但实际上 Docker 镜像不是一个完整文件,而是由多个 Layer 组成。

例如:

css 复制代码
镜像A

Layer1  Ubuntu基础层
Layer2  Java环境
Layer3  应用代码


镜像B

Layer1  Ubuntu基础层
Layer2  Java环境
Layer4  另外代码

其中:

复制代码
Layer1
Layer2

两个镜像共享。

所以删除镜像 A:

css 复制代码
docker rmi 镜像A

Docker 只能删除:

复制代码
没有任何引用的 Layer

而共享 Layer 会继续保留。

因此:

删除一个几 GB 的镜像,磁盘可能只释放几 MB,甚至 0MB。


二、真正占空间的大户:Build Cache

很多情况下,占用空间最多的不是镜像,而是:

复制代码
Build Cache

例如:

频繁执行:

bash 复制代码
docker build .

每一次构建都会产生缓存:

markdown 复制代码
build cache
    |
    ├── 基础镜像缓存
    ├── 中间层缓存
    ├── 编译缓存
    └── 临时构建层

这些缓存:

  • 不显示在 docker images
  • 不属于运行中的容器
  • 但是会一直占用磁盘

几十 GB,甚至几百 GB 都很常见。


三、查看 Docker 真正占用情况

不要只看:

bash 复制代码
docker images

应该使用:

bash 复制代码
docker system df -v

输出类似:

sql 复制代码
TYPE            TOTAL     ACTIVE    SIZE

Images          20        5         80GB

Containers      10        2         5GB

Local Volumes   8         3         50GB

Build Cache                         200GB

重点关注:

复制代码
Build Cache

很多时候真正的问题就在这里。


四、清理 Docker 无用资源

1. 清理未使用资源

执行:

bash 复制代码
docker system prune -a

会清理:

  • 未使用镜像
  • 已停止容器
  • 未使用网络
  • 构建缓存

执行前 Docker 会提示:

sql 复制代码
WARNING! This will remove:
 - all stopped containers
 - all networks not used by at least one container
 - all images without at least one container associated
 - all build cache

确认即可。


2. 如果需要删除 Volume

Volume 可能保存:

  • 数据库文件
  • 上传文件
  • 持久化数据

如果确定不要:

bash 复制代码
docker system prune -a --volumes

会额外删除:

复制代码
未使用 Volume

⚠️ 注意:

如果里面有数据库数据,请谨慎执行。


五、Windows + Docker Desktop + WSL2 特殊问题

如果你使用:

markdown 复制代码
Windows
 +
Docker Desktop
 +
WSL2

可能出现:

Docker 已经清理完成,但是 Windows 磁盘空间没有回来。

原因:

Docker Desktop 默认把 Linux 文件系统存储在:

复制代码
.vhdx

虚拟磁盘文件中。

例如:

常见路径:

kotlin 复制代码
C:\Users\用户名\AppData\Local\Docker\wsl\data\ext4.vhdx

但是不同版本、不同安装位置可能不同。

例如:

makefile 复制代码
E:\Docker\DockerDesktopWSL\disk\docker_data.vhdx

或者:

makefile 复制代码
C:\Users\31094\AppData\Local\Docker\wsl\main\ext4.vhdx

六、为什么清理 Docker 后 VHDX 不变小?

这是 WSL2 的设计机制。

过程:

markdown 复制代码
Docker删除数据

        ↓

Linux虚拟磁盘内部空间释放

        ↓

ext4.vhdx 文件大小不自动缩小

        ↓

Windows磁盘空间仍然被占用

也就是说:

内部:

复制代码
100GB → 20GB

但是:

Windows看到:

复制代码
ext4.vhdx 仍然100GB

七、正确释放 Windows 磁盘空间

第一步:关闭 Docker 和 WSL

退出 Docker Desktop。

然后执行:

powershell 复制代码
wsl --shutdown

确保 WSL 虚拟机停止。


第二步:找到真实 VHDX 文件

不要固定认为一定是:

复制代码
ext4.vhdx

应该查找 Docker 数据目录。

重点:

找体积最大的 .vhdx 文件。

例如:

复制代码
docker_data.vhdx     400GB

ext4.vhdx             300GB

其他文件              10MB

通常最大的就是 Docker 数据盘。


第三步:使用 DiskPart 压缩

管理员身份打开 PowerShell:

执行:

powershell 复制代码
diskpart

进入:

text 复制代码
DISKPART>

选择你的 VHDX:

例如:

text 复制代码
select vdisk file="C:\Users\31094\AppData\Local\Docker\wsl\main\ext4.vhdx"

成功:

复制代码
DiskPart 已成功选择虚拟磁盘文件。

然后执行:

text 复制代码
compact vdisk

等待:

复制代码
100 百分比已完成

DiskPart 已成功压缩虚拟磁盘文件。

退出:

text 复制代码
exit

八、实际效果

完成后:

css 复制代码
Docker清理前

ext4.vhdx
400GB


执行:

docker system prune -a

+

compact vdisk


之后:

ext4.vhdx
几十GB

Windows 磁盘空间真正释放。


九、完整推荐流程

以后 Docker 占空间,按照这个顺序:

1. 查看占用

bash 复制代码
docker system df -v

2. 清理 Docker

bash 复制代码
docker system prune -a

需要清 Volume:

bash 复制代码
docker system prune -a --volumes

3. Windows Docker Desktop

关闭:

powershell 复制代码
wsl --shutdown

压缩:

text 复制代码
diskpart

select vdisk file="xxx.vhdx"

compact vdisk

总结

Docker 删除镜像后空间没有释放,通常不是删除失败,而是:

  1. 镜像 Layer 共享,没有真正删除
  2. Build Cache 占用大量空间
  3. Docker Desktop WSL2 的 VHDX 不会自动缩小

真正完整释放空间,需要:

bash 复制代码
docker system df -v

docker system prune -a

wsl --shutdown

diskpart

compact vdisk

这样才能让 Docker 占用的磁盘空间真正回到 Windows。


本文实际验证环境:Windows + Docker Desktop + WSL2。 不同版本 Docker Desktop 的 VHDX 路径可能不同,判断标准不是路径,而是找到 Docker 使用的最大 .vhdx 文件。

相关推荐
高明珠2 小时前
麒麟 V10 SP1 排查实录:ttyS5 每 10 秒莫名收到一批报文,元凶是 eGTouchD
后端
卷无止境2 小时前
Python FFI 技术深度解析:ctypes、cffi 与 pybind11 的性能差异与实践挑战
后端·python
ServBay2 小时前
AI Gateway 是什么?为什么每个平台都在做
后端·aigc·ai编程
SamDeepThinking2 小时前
Vibe Coding最重要的是Spec
后端·程序员·ai编程
掘金_答案2 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
妙码生花2 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十三):权限规则管理器
后端·go·gin
Kim_wang3 小时前
agent项目部署流程
人工智能·后端
Zhu7583 小时前
在Docker环境部署ApacheGuacamole,对接PG数据库
数据库·docker·容器
程序员天天困3 小时前
优雅记录操作日志:从注解到 SpEL 的全链路实践与开源方案对比
java·后端