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 文件。

相关推荐
考虑考虑33 分钟前
cmd局部设置java变量
运维·后端·自动化运维
生活爱好者!1 小时前
哇!影视新玩法!docker部署NEOWATCH NAS
运维·docker·容器
陈随易3 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
cpolar技术支持4 小时前
Docker 容器启动失败怎么查?端口、日志、权限与网络排障完整教程
linux·docker·容器·cpolar·网络排障
wing985 小时前
从codex转战workbuddy使用一周的感受
前端·人工智能·后端
EatFan5 小时前
Java接入支付宝 JSAPI 支付保姆教程(二):流程讲解与前后端代码讲解
前端·spring boot·后端·微信小程序·小程序·uni-app
步行cgn5 小时前
Spring 报错:No bean class specified on bean definition 的原因与解决
java·后端·spring
凤山老林5 小时前
Spring Boot 整合 Flowable 的企业级落地指南
数据库·spring boot·后端·flowable·工作流
苏三说技术5 小时前
Kafka已正式接入AI
后端
企业数字化笔记5 小时前
AI写的系统出现504怎么办?接口超时和数据库慢查询排查
数据库·后端