/var/lib/docker 会不断增长,直到变成整块磁盘的问题。解决办法只有一条命令,但盲目执行正是很多人删掉自己正要基于它构建的基础镜像的原因。先看清楚,再清理。
1. 先看看空间去哪了
$ clai 显示 docker 占用了多少磁盘空间,还能回收多少→ docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLEImages 47 13 28.88GB 20GB (69%)Containers 16 9 126.8MB 513.8kB (0%)Local Volumes 38 7 6.311GB 4.084GB (64%)Build Cache 181 0 0B 0B
先看 RECLAIMABLE 这一列。这里镜像是大头,卷排第二,容器基本可以忽略。
2. 安全的清理
$ clai 删除已停止的容器、悬空镜像和未使用的网络→ docker system prune
普通的 prune 会清掉已停止的容器、悬空镜像(没有任何标签的层)、未使用的网络和构建缓存。它不会碰带标签的镜像和卷。这条命令可以放心执行,不用多想。
3. 激进的清理
$ clai 删除所有没有正在运行的容器在使用的镜像→ docker system prune -a⚠ CAUTION — 会删除所有未被运行中容器使用的镜像
-a 把"未使用"的定义从没有标签扩大到当前没有运行中的容器在使用。你精心拉取的那个 4GB 基础镜像,如果现在没有任何容器在运行,也会被算作未使用——下次构建时你得重新下载它。
4. 卷:谁也没想到的空间
$ clai 列出没有容器在使用的 docker 卷→ docker volume ls -qf dangling=true
Prune 默认不会碰卷,这是故意的——数据库就存在那里。先列出来,认清名字,然后再决定。docker volume prune 删除的数据,按定义是没有备份的。
5. 只清理构建缓存
$ clai 清理一周以前的 docker 构建缓存→ docker builder prune --filter 'until=168h'
在 CI 机器上,这通常是收益最大、也最安全的操作。--filter until= 让你保留最近的层,这样下次构建仍然很快。
6. 防止再次发生
$ clai 把 docker 容器日志文件限制为 10 兆和 3 个文件→ sudo tee /etc/docker/daemon.json <<'EOF'{"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}}EOF
容器日志默认没有轮转。这是唯一能防止最常见的重复问题的设置。它只对守护进程重启之后新建的容器生效。
常见陷阱
prune -a在什么都没运行时会删掉一切。 "使用中"的定义是有正在运行的容器,而不是你喜欢的镜像。先启动你的服务栈,或者改用--filter 'until=720h'。- 在 Docker Desktop 上,prune 不会缩小已满的磁盘。 在 macOS 和 Windows 上,虚拟机的磁盘镜像不会自动把空间还给宿主机。
- 被清理的卷不会再回来。 没有回收站。清理卷之前,每次都要先备份。
相关问题
docker system prune 和 docker image prune -a 有什么区别? system prune 一次清理容器、网络、镜像和构建缓存;image prune -a 只删除镜像,但连带标签的也会删。
为什么 /var/lib/docker/overlay2 这么大? 那里存的是镜像和容器的层。不要手动删除里面的任何东西——元数据存在别处,手动删除会破坏镜像存储。用 prune 就好。
能看看哪个镜像最大吗? docker image ls --format '{{.Size}}\t{{.Repository}}:{{.Tag}}' | sort -rh 可以按大小排序。
相关阅读
CliAI 会把 prune -a 标记为 CAUTION,并在执行前询问——因为两种 prune 之间的差异就是 20GB 的重新下载。一行命令安装。