Watch at Ease看见世界,读懂生活。

科技 · 实用指南

Docker 报“设备上没有空间”,但 df 看起来还有余量?先核对真实存储路径

Docker 可能写入另一挂载点、耗尽 inode,或填满特定 Buildx 构建器。清理或迁移前,先把实际路径映射到文件系统。

原创编辑示意图:将 Docker、containerd 与 Buildx 存储路径映射到真实文件系统检查
原创概念图:先把每个活动存储路径映射到挂载点,再比较块、inode 与 Docker 占用。 Watch at Ease

整机 df 看起来正常,并不代表接收 Docker 写入的文件系统还有空间。失败的拉取、构建或容器可能位于独立挂载点,也可能是 inode 耗尽,或属于你没有检查的 Buildx 构建器。

先保留完整命令与错误,再确认当前守护进程、实际存储路径和所选构建器。逐一路径映射文件系统、测量资源,只有所有证据一致后才清理。

保留失败操作并确认当前上下文

记录 ENOSPC 出现在 pull、BuildKit 构建步骤、容器启动、应用写入还是日志输出,并保留错误中出现的完整路径。修复拉取缓存不一定能修复绑定挂载的应用目录。 容器的可写层与它能访问的每个主机路径,也不属于同一个存储归属。

用 docker context show 确认上下文,并核对 docker info 中的 Docker Root Dir 与存储驱动;再用 docker buildx ls 记录相关构建器。远程上下文或 Docker Desktop 不应套用本机 /var/lib/docker 假设。 此时应停止套用本机路径,使用实际守护进程的文档和存储视图。

把每个真实路径映射到文件系统

对适用路径执行 findmnt --target PATH --output SOURCE,FSTYPE,SIZE,USED,AVAIL,USE%,TARGET。除了 Docker Root Dir,Engine 29 的 containerd 镜像存储还应检查 /var/lib/containerd。 这一额外路径限于使用 containerd 镜像存储的全新安装;官方文档明确指出 data-root 不迁移该镜像和快照存储。

不要从路径名称推断文件系统。子目录可能位于独立挂载、逻辑卷或网络文件系统;错误若指向绑定挂载或应用目录,也要映射该路径。 保存映射出的挂载目标和来源,使后续清理前后的测量针对同一文件系统。

区分块空间与 inode 耗尽

分别执行 df -h PATH 与 df -i PATH。文件系统可能还有大量字节,却没有 inode 可创建新文件;反过来也一样。配额、只读状态和 I/O 错误应另行处理。 保留空间也应独立检查;仅凭 ENOSPC 不能证明是 Docker 对象导致。

字节耗尽时找出最大归属;inode 耗尽时统计文件数量,而不是只看目录字节。删除前必须把高占用树与 Docker、containerd、构建器、绑定挂载或日志对应起来。 查找大占用时避免意外跨入无关挂载点,并保留所有带状态的数据。

prune 前先确认 Docker 与构建器归属

用 docker system df -v 查看守护进程管理的镜像、容器、本地卷与构建缓存;对失败构建所用的构建器执行 docker buildx du --builder NAME。 输出须区分可回收、共享、可变和使用中记录;Docker 文档说明正在使用的记录即使用 --all 也不会删除。

优先删除已确认无用的单个容器、镜像或特定构建缓存。docker system prune 范围更宽,而卷需要显式选项;执行前检查 Compose 项目、命名卷、备份和回滚需求。 卷可能包含持久数据,停止容器或无引用状态并不代替归属和备份判断。

只迁移已证明确实已满的存储

若保留需求超过文件系统容量,应在维护窗口按实际存储制定迁移计划。停止写入、保存配置与备份,并按当前守护进程或 containerd 文档操作;只改 data-root 不会迁移 Engine 29 的 containerd 镜像存储。 迁移前也要核实文件归属与权限。

清理或迁移后,再对同一路径执行 findmnt、df -h 与 df -i,然后重跑原失败的 pull、build 或写入。还要确认镜像、容器、卷和应用数据仍然存在。 只重启守护进程或看到错误消失还不够:原操作和目标文件系统都必须显示预期结果。

原创编辑示意图:把 Docker ENOSPC 分为块、inode、构建缓存或检查错挂载点
原创概念图:先确定耗尽资源和归属,再选择小范围清理或迁移。 Watch at Ease