Docker 又吃了我 40GB 硬盘:从诊断到清理的完整指南
摘要:Docker 在 macOS 上运行几个月后,磁盘占用轻轻松松超过 30GB——不是因为镜像太多,而是因为虚拟机磁盘镜像只增不减、构建缓存从不自动清理、退出容器后的卷成了孤儿。本文从三层诊断入手——Docker 自身的
system df数据、macOS 文件系统层的 SpacePeek 空间分析、以及 Docker Desktop 的磁盘镜像占用——给出分级清理策略(安全 / 标准 / 激进),每一步标注可回收空间量和风险等级。文末提供按月执行的自动化脚本。
本文信息:基于 Docker Desktop for Mac (Apple Silicon)、macOS 15.0 Sequoia、Docker Engine 26+ 实测。清理命令适用于 Docker 26+ 版本,低版本需注意命令兼容性。
一、问题背景
Docker 的磁盘占用不是 bug,是设计
Docker 在 macOS 上的运行机制和 Linux 完全不同。在 Linux 上,Docker 直接跑在宿主机内核上,镜像和容器数据存在本机文件系统里。但在 macOS 上,Docker 跑在一个轻量 Linux 虚拟机里——这个虚拟机的磁盘镜像(Docker.raw)是一个只增不减的稀疏文件。
关键问题就出在"只增不减"这四个字。
你拉了一个 2GB 的镜像,用完了删掉——虚拟机镜像文件不会缩小。你跑了 100 次 docker build,每次都产生构建缓存——虚拟机镜像文件只增不减。你创建了 10 个数据卷,项目结束后删了容器但忘了删卷——虚拟机镜像文件继续增大。
结果就是:用了三个月 Docker 之后,你去 ~/Library/Containers/com.docker.docker/ 一看——Docker.raw 已经 45GB 了。
二、三层诊断:找到 Docker 到底吃了你多少空间
第 1 层:Docker 自己的数据统计
docker system df
输出解读:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 45 12 8.7GB 5.2GB (59%)
Containers 18 6 1.1GB 620MB (55%)
Local Volumes 5 3 120MB 50MB (40%)
Build Cache 0 0 0B 0B
怎么看:
Images的RECLAIMABLE数字——这些是可以安全回收的未使用镜像Containers的RECLAIMABLE——已退出但未删除的容器Local Volumes的RECLAIMABLE——未被任何容器挂载的卷(孤儿卷)Build Cache——docker build的中间层缓存
进阶命令:
docker system df -v # 详细列出每个镜像/容器/卷的大小
第 2 层:macOS 文件系统层的实际占用
# 查看 Docker 虚拟机磁盘镜像的实际大小
ls -lh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
典型输出:45GB。但 Docker Desktop 设置里显示"已使用 28GB"——为什么差 17GB?因为 Docker.raw 是稀疏文件,它从 0 开始只增不减,即使你删除了镜像,这个文件也不会自动缩小。这是 macOS 版 Docker 最核心的空间问题。
如果你装了 SpacePeek:在 Finder 里进入 ~/Library/Containers/com.docker.docker/ → 按空格 → 饼图会告诉你 Data/vms 占了 95% 以上。不需要手动逐层 ls -lh,一眼定位。

第 3 层:Docker Desktop 的资源面板
Docker Desktop → 右上角齿轮 Settings → Resources → 可以看到:
- Disk image size:当前磁盘镜像的实际占用(包含稀疏文件中的"空洞")
- Disk image max size:镜像文件允许的最大体积(默认通常设为 64GB 或 128GB)
如果 Disk image size 接近 max size,你需要进行"激进清理"(见下文)。
三、分级清理策略
⚠️ 清理原则:安全优先。先从低风险操作开始,释放量不够再逐步升级。
🟢 Level 1:安全清理(零风险,释放 5-15GB)
这些命令只删除未被任何运行中容器使用的资源。不会影响你正在开发的项目。
# 1. 清理悬空镜像(<none>:<none>)
docker image prune -f
# 2. 清理已停止的容器
docker container prune -f
# 3. 清理未被使用的卷
docker volume prune -f
# 4. 清理构建缓存
docker builder prune -f
每次预期释放:5-15GB(取决于你上次清理是什么时候)。
🟡 Level 2:标准清理(低风险,释放 10-25GB)
这些命令会删除所有未被运行中容器使用的镜像、构建缓存和网络。不会影响正在运行的容器,但会删除已停止容器的镜像和缓存。
# 一条命令搞定 Level 1 + Level 2 的全部清理
docker system prune -a --volumes -f
参数解释:
| 参数 | 作用 |
|---|---|
-a | 删除所有未被使用的镜像(不只是悬空的) |
--volumes | 同时删除未被使用的卷 |
-f | 跳过确认提示 |
⚠️ 注意:-a 会删除所有未运行容器的镜像。如果你有一个停止的容器需要保留其镜像,先用 docker images 确认。
每次预期释放:10-25GB。
🔴 Level 3:激进清理(中风险,释放 20-40GB)
场景:Level 2 清理之后,Docker.raw 文件仍然很大——因为你已经删除了所有可清理的数据,但磁盘镜像文件本身没有缩小。
原因:Docker Desktop 的虚拟机磁盘镜像是稀疏文件,内部数据删除后,占用的空间不会还给 macOS。你需要手动压缩这个文件。
操作步骤:
1. Docker Desktop → Troubleshoot → Reset to factory defaults
⚠️ 这会删除所有容器、镜像、卷、构建缓存——相当于重装 Docker
2. 替代方案(保留部分数据):
Docker Desktop → Settings → Resources → Advanced →
将"Disk image size"调到一个较小的值(如 32GB)→ Apply & Restart
Docker 会自动压缩镜像文件到设定值以下
注意:Level 3 只在你确认"所有重要的 Docker 数据已经不需要了"时执行。如果你有需要保留的镜像,先用 docker save 导出。
四、预防:写一个按月执行的脚本
比清理更重要的是——不要回到"每季度突然发现 Docker 占了 50GB"的循环。
#!/bin/bash
# ~/scripts/docker-monthly-cleanup.sh
# 每月执行一次,放在 crontab 里
echo "===== $(date) =====" >> ~/docker-cleanup.log
echo "清理前使用情况:" >> ~/docker-cleanup.log
docker system df >> ~/docker-cleanup.log
echo "→ 清理悬空镜像..." >> ~/docker-cleanup.log
docker image prune -f >> ~/docker-cleanup.log 2>&1
echo "→ 清理退出容器..." >> ~/docker-cleanup.log
docker container prune -f >> ~/docker-cleanup.log 2>&1
echo "→ 清理构建缓存..." >> ~/docker-cleanup.log
docker builder prune -f >> ~/docker-cleanup.log 2>&1
echo "清理后使用情况:" >> ~/docker-cleanup.log
docker system df >> ~/docker-cleanup.log
echo "---" >> ~/docker-cleanup.log
设置每月自动执行:
chmod +x ~/scripts/docker-monthly-cleanup.sh
crontab -e
# 加入:0 9 1 * * ~/scripts/docker-monthly-cleanup.sh
# 每月 1 号上午 9 点执行
五、关于 macOS 版 Docker 的一个认知纠正
有人会说"Docker 在 macOS 上就是吃资源"——这不完全对。
Docker Desktop 在 macOS 上需要虚拟机,这是物理上无法绕过的事实。但"磁盘镜像只增不减"的原因不是 Docker 做得差,而是 macOS 的 Hypervisor 框架对稀疏文件的管理方式和 Linux 的 OverlayFS 不同。
你能做的是:主动管理。每月 run 一次 Level 1-2 清理 + 看一眼 SpacePeek 确认 Docker.raw 没膨胀到离谱。养成这个习惯之后,Docker 的磁盘占用不再是问题。
六、总结
三点核心
-
Docker on macOS 的磁盘膨胀分两层:Docker 内部的数据层(镜像/容器/卷/缓存,用
docker system df诊断)和 macOS 文件系统层(Docker.raw虚拟机磁盘镜像,用ls -lh或 SpacePeek 诊断)。两层都要清理,缺一不可。 -
清理有三级,按需升级:Level 1(悬空资源,5-15GB,零风险)→ Level 2(全部未使用资源,10-25GB,低风险)→ Level 3(压缩磁盘镜像,20-40GB,中风险)。绝大多数情况 Level 2 就够了。
-
预防比清理更重要。 一个月执行一次 Level 1 清理,比半年执行一次 Level 3 重置更安全、更省时间。配合 SpacePeek 的 Finder 侧随手按空格,你可以在日常浏览文件时顺便知道
Docker.raw有没有偷偷膨胀。
涉及的工具
| 工具 | 文中角色 | 获取 |
|---|---|---|
docker system df | Docker 内部数据诊断 | Docker 自带 |
docker system prune | Docker 内部数据清理 | Docker 自带 |
| SpacePeek | macOS 文件系统层诊断 | App Store 免费 |
| crontab | 自动执行清理脚本 | macOS 自带 |
测试环境:Docker Desktop for Mac (Apple Silicon) / Docker Engine 26 / macOS 15.0 Sequoia / 2026 年 7 月
你的 Docker 最长多久没清理过?评论区晒一下
docker system df的 RECLAIMABLE 数字——让我看看谁的最离谱。
更多推荐
所有评论(0)