必须先删除所有容器(含已停止)以解除对隐藏镜像层的引用,再执行 docker image prune -a -f 清理未被引用的镜像层,最后通过 docker system prune -a -f --volumes 彻底释放 overlay2 中残留空间。

彻底清理被容器快照占用的“隐藏镜像层”,关键在于理解 Docker 的分层机制和引用关系——所谓“隐藏层”并非独立存在,而是未被任何标签(tag)引用、但仍在被运行或已停止容器的文件系统快照(如 overlay2 中的 diff 目录)所依赖的镜像层。这些层不会出现在 docker images 列表中,却真实占用磁盘空间。要真正释放它们,必须解除容器对底层镜像的引用,并清理残留数据。
确认哪些层被容器实际使用
Docker 容器启动时会基于镜像创建可写层(container layer),但其只读基础仍来自镜像层。即使容器已停止,只要它未被删除,其 rootfs 仍持有对底层镜像层的引用,导致这些层无法被 docker image prune 清理。
- 列出所有容器(含已停止):
docker ps -a - 检查某镜像是否被容器祖先引用:
docker ps -a --filter ancestor=nginx:1.21 - 查看容器实际使用的镜像层(需 inspect):
docker inspect -f '{{.Image}}' <container_id></container_id>
先清理容器,再释放镜像层
镜像层能否被回收,取决于是否有活跃引用。停止的容器仍构成引用,因此必须显式删除容器本身,而非仅 stop。
- 删除所有已停止容器:
docker container prune -f - 强制删除所有容器(含运行中):
docker rm -f $(docker ps -aq) - 特别注意:使用
docker kill不解除引用,必须用rm
清理无引用镜像与悬挂层
容器删除后,原先被其引用的镜像层若不再被任何镜像标签或其它容器指向,就变为“悬挂层”(dangling layers)。此时才能安全回收。
- 清理所有悬空镜像(无 tag 的中间层):
docker image prune -f - 清理所有未被任何容器引用的镜像(含带 tag 的旧版本):
docker image prune -a -f - 同步清理构建缓存和网络等资源:
docker system prune -a -f --volumes
验证底层存储是否释放
命令行清理后,部分空间可能仍未释放,尤其在 overlay2 存储驱动下——Linux 的延迟回收机制可能导致 /var/lib/docker/overlay2 中目录残留。
- 查看 Docker 根目录实际占用:
sudo du -sh $(docker info | grep "Docker Root Dir" | cut -d' ' -f4) - 检查是否存在孤立的 diff 目录:
sudo find /var/lib/docker/overlay2 -maxdepth 1 -type d -name "*-removeme" -o -name "*-init" - 不建议手动
rm -rfoverlay2 子目录;如确需深度清理且无运行容器,可重启 dockerd:sudo systemctl restart docker,触发自动垃圾回收











