先用docker system df查看空间占用分布,再按镜像、容器、卷、构建缓存四类资源差异精准清理:镜像分dangling与unused;容器只删exited/created状态;卷必须inspect确认内容再删;构建缓存可安全清理但影响后续构建速度。

直接说结论:别一上来就 docker system prune -a,先用 docker system df 看清空间被谁占了,再按需清理——镜像、容器、卷、构建缓存四类资源行为完全不同,混着删容易误伤或白删。
怎么一眼看出 Docker 磁盘被谁吃掉了
执行 docker system df,你会看到一张表,关键列是 SIZE 和 RECLAIMABLE:
-
Images:只读层总和,RECLAIMABLE高说明有大量悬空镜像(<none>:<none></none></none>)或未被引用的带标签镜像 -
Containers:含运行中和已停止的容器可写层,RECLAIMABLE高 = 一堆exited容器没清理 -
Volumes:独立于容器生命周期,RECLAIMABLE高 ≠ 安全可删,得确认里面有没有数据库数据、日志归档等 -
Build Cache:docker build产生的中间层,不绑定镜像,删了不影响运行,但下次构建会变慢
如果 Volumes 占比异常高,别急着 prune,先 docker volume ls -q | xargs -I {} docker volume inspect {} 看挂载路径和用途。
安全删容器:只动 exited 和 created 状态
正在运行的容器不能删,已停止的容器可放心清理,但要注意状态差异:
-
docker container prune -f:只删exited、created、dead等非运行态容器,最常用也最安全 -
docker rm -f $(docker ps -aq -f status=exited):效果同上,适合脚本里用,-f强制删避免报错中断 - 别用
docker rm -f $(docker ps -aq)清理“所有容器”,它会杀掉running的服务,线上环境等于自毁 - 如果容器名有规律(比如都带
-test),用docker rm -f $(docker ps -aq --filter "name=-test$")更精准
删镜像要分清 dangling 和 unused
镜像分层机制决定了“删镜像”不是简单删文件:
-
docker image prune -f:只删dangling=true的镜像(即<none>:<none></none></none>且无任何容器引用),这是构建时没打标签或docker tag没跟上的中间层 -
docker image prune -a -f:删所有unused镜像,即没有容器(包括已停止的)在用的带标签镜像,比如你拉了nginx:1.25启了个容器又停了,再删这个镜像就会失败;但如果容器已删,它就变成unused,会被清掉 - 想删特定名字的镜像,别用
docker rmi $(docker images -q nginx),它可能匹配到nginx:alpine和my-nginx:dev,应加--filter:docker rmi $(docker images -q --filter "reference=nginx:*") -
docker images -f dangling=true查完再删,比盲删更可控
卷和构建缓存:删前必须确认用途
Volumes 是唯一真正可能丢数据的地方,Build Cache 则影响构建效率:
-
docker volume prune -f只删unused卷(没被任何容器--mount或-v挂载),但很多卷即使没挂载也存着备份或配置,删前用docker volume inspect <vol-name></vol-name>看Mountpoint路径,进目录扫一眼内容 -
docker builder prune -f清构建缓存,安全,但 CI/CD 流水线频繁构建的机器,删了会导致首次构建时间翻倍 -
docker system prune -a --volumes是终极命令,但它会连unused卷一起删,生产环境禁用;本地开发机定期跑一次可以,但记得提前备份关键卷 - 如果你用
docker-compose,docker compose down -v会删服务定义里的卷,比全局prune更精准
最容易被忽略的是:docker system prune 默认不删卷,但很多人以为它“全清”,结果发现 Volumes 还占着 30GB —— 因为卷的生命周期完全独立,Docker 不会替你判断哪些该留、哪些该扔。











