如何清理 Docker for Mac,又不丢数据
Docker Desktop 可能占用几十 GB,因为镜像、容器可写层、构建缓存和数据卷都位于一块 Linux 虚拟磁盘中。这些类别并不具备相同的可删除性。构建缓存通常可以重建,数据库卷却可能是重要数据的唯一副本。
安全清理要从 Docker 自己的清单开始,而不是从范围最大的 prune 命令开始。
为什么 Docker 空间没有立刻回来
Docker Desktop 在 macOS 上运行一台 Linux 虚拟机,数据通常保存在名为 Docker.raw 的稀疏虚拟磁盘中。Docker 的 Mac 存储说明会引导到「Docker Desktop > Settings > Resources > Advanced」,这里可以查看位置、磁盘上限和实际占用。移动虚拟磁盘应使用这个控制项,不要用 Finder。
稀疏文件拥有很大的逻辑上限,但物理分配可能小得多,所以只看 ls -lh 会让它看起来远大于当前真实占用。
先查看 Docker 自己统计的内容:
docker system df -v
详细视图会分别列出镜像、容器、本地卷和构建缓存。「Reclaimable」表示 Docker 没有发现当前引用必须保留该对象,不代表你明天不会需要某个已停止容器、旧镜像或数据卷。清理前还要检查 docker ps -a 和 docker volume ls。
先从范围最窄的清理开始
始终从 Docker 内部回收,不要直接删除虚拟磁盘文件。先处理自己理解的类别:
docker builder prune --filter until=168h
docker image prune
docker container prune
第一条命令会移除七天以前的构建缓存,可以按自己的工作节奏调整时间。后两条命令会在删除悬空镜像和已停止容器前要求确认。每一步后再次运行 docker system df -v,观察究竟是哪项操作产生效果。
Docker 的清理说明把 docker system prune 定义为更宽的便捷命令。加入 -a 会删除所有未使用镜像,不只是悬空层;加入 --volumes 会把范围扩展到未使用的匿名数据卷,其中可能保存数据库文件或其他状态。
不要把 docker system prune -a --volumes 当作默认清理命令。任何数据卷清理前,先检查名称和所有权:
docker volume ls
docker volume inspect <volume-name>
Compose 创建的数据卷通常带有项目与服务标签。先确认所属项目,并导出或备份无法重建的数据,再删除。
让虚拟磁盘归还空间
执行 prune 后,Linux 文件系统内部先出现空闲块,macOS 不一定立即从稀疏磁盘拿回这些空间。当前 Docker 文档说明,Docker.raw 通常会在数秒内归还符合条件的主机空间;旧式 Docker.qcow2 镜像依赖后台进程,可能需要数分钟。
重新测量实际磁盘占用,不要用文件逻辑上限判断。恢复出厂设置不是压缩,它会销毁本地容器、镜像、数据卷和设置。只有当完整损失本来就是目标,而且重要卷数据已经导出时,才使用它。
为什么文件会增长,又不会自动缩小
Docker Desktop 运行 Linux 虚拟机,Docker.raw 就是这台虚拟机的稀疏磁盘。来宾系统写入时文件会增长,但来宾删除内容后,不会自动把所有空间交还 macOS。
移除镜像只会先在虚拟机文件系统中把块标为空闲。只有来宾发出 TRIM 或 discard,Docker Desktop 再利用 discard 与压缩,主机文件才会归还符合条件的块。具体时间取决于 Docker Desktop 版本和磁盘镜像实现。
因此,Docker 内部逻辑清理与 macOS 物理容量变化必须分别测量。删除主机上的 Docker.raw,等同于销毁整个 Docker 环境。
先确认空间是不是 Docker 占的
Mole「分析」页这样的磁盘地图可以发现虚拟磁盘及其物理占用。哪些内部对象仍被引用,必须由 Docker 自己的命令行判断。两个视图回答不同问题:macOS 说明容量分配在哪里,Docker 说明其中包含什么。
清理时按这个顺序
运行 docker system df -v,确认旧项目和有状态数据卷,导出唯一数据,再一次只清理一个类别。同时复查 Docker 内部总数和 macOS 物理容量。
只有检查扩展范围后,才使用宽泛 prune 参数。不要把恢复出厂设置当作日常空间回收。最快又相对安全的收益通常来自旧构建缓存,不是身份未知的数据卷。