社群中有运维同行在接手环境时,发现服务器上的 Docker 存在大量 <none> 镜像,一时间不知如何处理。

这个问题其实很多使用 Docker 的开发者或运维人员都会遇到。本文将详细讲解这些 none 镜像产生的原因、如何正确安全地清理,以及如何从源头避免再次出现大量无名镜像。
1 none 镜像是怎么产生的?
首先需要明确,这些 <none> 镜像通常并非异常,而是 “被新镜像顶掉了标签(tag)的旧镜像”。
最常见的来源有以下四种:
1.1 反复 build 时使用 latest 标签
在构建镜像时,如果习惯性地使用 latest 标签:
docker build -t app-api:latest .
当你第二次执行相同的构建命令时,会生成一个内容不同的新镜像,latest 这个标签会从旧镜像转移到新镜像上。旧镜像的标签因此被移除,在镜像列表中就会显示为 <none>。
1.2 docker-compose / CI 流水线每次自动 build
在 docker-compose.yml 文件或 CI/CD 流水线配置中,如果指定了 build 操作并且镜像标签固定为 latest:
build: .
image: app-api:latest
那么,每次执行 docker-compose up --build 或流水线触发构建时:
- 都会覆盖
latest 标签。
- 都会制造一个失去标签的旧镜像,即
<none> 镜像。

开头提到的那位同行,正是遇到了这个问题。其 docker-compose 中设置了 latest 标签,流水线频繁调用就导致了大量 none 镜像堆积。
1.3 构建失败或中断
第三种情况是镜像构建过程失败或被意外中断。此时 Docker 可能已经生成了一些镜像层,但由于未能成功走到打标签(tag)的步骤,这些中间层也会以 <none> 的形式存在。
1.4 手动调整或删除标签
这种情况相对较少,即手动使用 docker tag 命令更改镜像标签,或使用 docker rmi 仅删除某个标签(而非镜像ID本身)。这些操作都会导致镜像实体仍然存在,但名字(标签)丢失,从而变成 <none>。
2 删了 <none>,磁盘空间却不降?
那位同行发现,即使使用 docker rmi 删除了一批 none 镜像,服务器的磁盘空间也未见明显下降。这是为什么呢?
原因在于:被删除的镜像层并没有被物理抹除,而是从“镜像层”,转变为了 “Build Cache 层”。
为什么会这样?这与现代 Docker 默认使用的构建引擎 BuildKit 有关。
当你使用 docker rmi 删除镜像时,Docker 会识别到这些镜像层来自之前的 docker build 操作。BuildKit 认为它们正好可以作为下次构建的缓存,以提高构建速度,于是就把它们“收编”进了 Build Cache。
我们可以通过 docker system df 命令来验证这一点。
删除前,系统占用情况可能如下:

删除一批 none 镜像后,再次查看:

对比两图可以看到,Images 的数量和大小确实减少了,但 Build Cache 的大小却相应增加了。磁盘总占用自然没有变化。
三、如何正确删除
请按照以下顺序操作,此过程不会影响任何正在运行的服务。为了万无一失,建议在执行前对重要环境进行备份或快照。
第一步:删除已停止的容器
首先清理掉所有已停止运行的容器,释放一部分关联资源。
docker container prune
第二步:删除 <none> 镜像
使用 Docker 提供的镜像修剪命令,它会删除所有未被容器引用的悬空(dangling)镜像,这正是 <none> 镜像的官方名称。
docker image prune
(系统会询问是否继续,输入 y 确认)
第三步:删除 Build Cache(关键步骤)
这是真正释放磁盘空间的关键。此命令会清理构建缓存,包括那些从镜像“转职”过来的缓存层。
docker builder prune
需要注意的是,清除缓存后,下一次执行 docker build 时会因为缺少缓存而变慢。但这能有效释放已被删除镜像占用的存储空间。
第四步:验证空间释放情况
最后,通过以下命令确认清理效果。
docker system df
df -h
此时,你应该能看到服务器的磁盘使用率有了明显的下降。
4 避坑操作
4.1 慎用 docker system prune -a
不要一上来就执行这个“强力”命令:
docker system prune -a
它会删除所有未被任何容器使用的镜像,包括那些有明确标签(如 nginx:latest)但当前未运行容器的镜像。这可能导致你之后需要时得重新拉取镜像,造成不必要的麻烦和时间浪费。该命令还可能清理停止的容器等资源,存在一定风险。
4.2 严禁手动删除 Docker 存储目录
切勿因为磁盘占用高,就直接去操作系统层面删除 Docker 的数据目录,例如:
/var/lib/docker/overlay2
这是 Docker 容器和镜像的底层存储位置,直接删除文件会破坏 Docker 内部的数据层关系,极有可能导致所有容器无法运行、数据丢失,造成严重的服务故障。
请牢记上文所述的“清理四部曲”,使用 Docker 提供的正规命令进行管理,不要直接操作底层文件。
更重要的是理解 Docker 磁盘占用的这套逻辑(镜像层与构建缓存的转换关系),以后再处理此类问题就能得心应手了。
希望这篇关于云原生基础设施中镜像管理的指南能对你有所帮助。如果你在实践过程中遇到其他棘手问题,欢迎在技术社区进行交流探讨,例如在云栈社区的相关板块分享你的经验。
