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 删除镜像后空间没有释放,通常不是删除失败,而是:
- 镜像 Layer 共享,没有真正删除
- Build Cache 占用大量空间
- 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文件。