欢迎光临
专业的主机评测网站

Docker磁盘空间不足怎么办?镜像、容器与构建缓存清理教程

使用 Docker 部署网站或自建服务后,服务器磁盘可能越来越满。更新应用留下的旧镜像、反复构建产生的缓存、已经停止的测试容器,都可能继续占用空间。

但 Docker 占用大,也可能是数据库、上传文件和日志正在增长。清理前需要先确定空间用在哪里,再选择对应的处理方式。

本文适用于已安装 Docker Engine 的 Linux 服务器。请在 Docker 实际运行的服务器上操作,使用 root 或具备相应权限的账号。

Docker磁盘空间排查与镜像、容器、构建缓存清理教程

一、先确认哪个文件系统空间不足

查看服务器磁盘容量和使用率:

df -hT

重点关注 Use% 和 Mounted on,确定接近满载的是系统盘,还是保存 Docker 数据的数据盘。

如果还有剩余容量,却仍然提示 No space left on device,再检查 inode:

df -i

IUse% 接近 100%,可能意味着大量小文件耗尽了 inode,需要定位这些文件所在目录。

随后查看 Docker 的空间统计:

docker system df

常见分类如下:

分类主要内容排查方向
Images本地镜像及其镜像层是否保留了大量旧版本
Containers容器可写层是否有废弃容器或大量临时文件
Local VolumesDocker 数据卷是否为数据库、上传文件等业务数据
Build Cache镜像构建缓存是否经常在服务器上构建镜像

RECLAIMABLE 表示 Docker 判断可以回收的空间,不代表这些内容对业务没有价值。

例如,一个暂时没有容器引用的数据卷,仍然可能保存着需要恢复的数据库。

二、查看具体镜像和容器的占用

查看详细统计:

docker system df -v

镜像部分需要注意三个字段:

  • SIZE:镜像总大小。
  • SHARED SIZE:与其他镜像共享的空间。
  • UNIQUE SIZE:仅由该镜像使用的空间。

多个镜像可能共享相同的底层数据,因此不能把每个镜像的 SIZE 直接相加,作为实际占用。

接着查看包括已停止容器在内的可写层大小:

docker ps -a --size \
  --format 'table {{.Names}}\t{{.Status}}\t{{.Size}}'

这里的 SIZE 主要反映容器可写层,括号里的 virtual 包含镜像数据。

该统计不包含容器挂载的数据卷、宿主机目录,以及 Docker 日志驱动保存的日志。 因此,容器显示占用很小,也可能对应一个很大的数据库目录。

这些统计可能涉及较多文件扫描,容器和文件数量较多时,建议在业务低峰执行。

三、分别清理无用镜像与构建缓存

1. 清理悬空镜像

先查看悬空镜像:

docker image ls --filter dangling=true

悬空镜像通常没有标签,也没有容器引用。确认不需要保留后,执行:

docker image prune

命令会提示确认,输入 y 后开始清理。

如果考虑使用 docker image prune -a,需要知道它的范围更大:所有没有被任何现存容器引用的镜像,都可能被删除,包括带标签的镜像。

这可能包含为版本回退预留的镜像。仅保存在本机、没有推送到仓库的自建镜像,也应先确认能否重新构建。

2. 清理构建缓存

如果 Build Cache 占用明显,可以执行:

docker builder prune

根据提示确认后,Docker 会清理符合条件的构建缓存。默认不加 -a 时,清理范围为悬空构建缓存。

构建缓存用于加速后续构建。删除后,部分步骤需要重新执行,可能重新下载依赖,但该命令不用于删除运行中的容器或业务数据卷。

使用多个独立 Buildx 构建器时,各构建器的缓存需要分别检查,不能把一次清理理解为清空所有构建缓存。

四、逐个删除确认废弃的停止容器

容器停止后,可写层仍然占用磁盘。先列出已经退出的容器:

docker ps -a --filter status=exited \
  --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'

不要仅凭 Exited 就判断它可以删除。它也可能是暂时停机的业务容器,或需要保留现场的故障容器。

假设确认要检查的容器叫 old-test,先替换下面的名称:

old_container='old-test'

docker inspect --format '{{.State.Status}}' "$old_container"

docker inspect \
  --format '{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}' \
  "$old_container"

第二条检查命令会列出挂载类型、宿主机来源及容器内路径。

确认容器确实废弃、可写层中的重要文件已经备份,并且不再需要保留其配置和日志后,执行:

docker rm "$old_container"

这条命令会直接删除指定容器及其可写层。 示例没有使用 -f 强制删除运行中的容器,也没有使用 -v 删除关联匿名卷。

挂载目录或数据卷能够保留,并不意味着容器内部所有文件都能保留。没有写入持久化挂载位置的数据,会随可写层一起消失。

五、数据卷和挂载目录要单独判断

如果占用主要来自 Local Volumes,或者容器可写层很小、磁盘却持续增长,就需要查看应用的数据挂载。

以 myapp 为例,替换为实际容器名称:

container_name='myapp'

docker inspect \
  --format '{{range .Mounts}}{{println .Type .Source "->" .Destination}}{{end}}' \
  "$container_name"

常见类型有:

类型含义处理方式
bind直接挂载宿主机文件或目录检查对应 Source 路径
volume使用 Docker 管理的数据卷结合卷名、应用配置和备份情况判断

假设确认某个 bind 挂载来源为 /home/myapp/data,可以查看该目录的占用:

du -sh -- /home/myapp/data

进一步查看一级子目录:

du -xhd1 -- /home/myapp/data | sort -h

这里的路径只是示例,需要换成检查到的实际路径。

如果大文件属于数据库、照片原图、用户上传文件或备份,应通过应用提供的清理、归档或备份保留策略处理。数据库数据文件尤其不能直接按大小删除。

不要手动删除 Docker 内部的镜像层目录,也不要把没有容器引用的数据卷直接视为垃圾。

六、docker system prune会删除哪些内容?

docker system prune 会同时清理多类资源。执行前,需要理解不同参数带来的范围变化:

命令主要清理范围
docker system prune已停止的容器、未使用的网络、悬空镜像和未使用的构建缓存
docker system prune -a在上述范围上,将镜像清理扩大到所有没有容器引用的镜像
docker system prune --volumes在默认范围上,增加未使用匿名卷的清理

默认不清理数据卷,并不意味着整个命令没有数据风险:已停止容器的可写层,也可能保存着没有备份的文件。

此外,清理命令通常提示的是删除类别,并不提供完整的逐项预览。因此,日常维护更适合先定位占用,再按镜像、缓存和废弃容器分别处理。

七、清理后检查空间和业务状态

完成对应清理后,再次查看:

df -hT
docker system df
docker ps --format 'table {{.Names}}\t{{.Status}}'

对比同一个文件系统的剩余空间,并打开实际网站或应用,检查关键功能。

如果释放空间很少,常见原因包括:镜像层仍被其他对象共享、占用来自正在使用的数据卷,或者空间主要消耗在日志和宿主机挂载目录。

后续维护时,应为日志设置轮转、为备份设置保留周期,并持续关注业务数据所在文件系统的容量。清理旧镜像和缓存能够回收闲置空间,持续增长的业务数据则需要单独规划。

赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

专业的主机评测网站

国内/国外VPS测评、云服务器评测,从VPS或IDC商家的资质、客服水平、售后服务、VPS线路、服务器硬件、主机性能等、访问速度进行云主机、IDC测评。

联系我们联系我们