跳至主要内容

Docker 删除镜像:如何清理未使用与悬空镜像

本指南将手把手演示如何安全高效地删除 Docker 镜像,回收磁盘空间、避免构建杂乱,并预防与存储相关的错误!
· 10分钟 阅读

使用 AI 探索

您在使用 Docker 时经常遇到磁盘空间不足吗?这并不罕见。

Docker 镜像是容器的基石,但它们会迅速累积并占用磁盘空间。镜像大小从几 MB 到数 GB 不等,因此定期清理对于保持系统性能至关重要。

好消息是——Docker 提供了多种命令,帮助您移除不必要的镜像并回收磁盘空间。了解这些命令及其适用场景,有望让“存储已满”的警告不再出现。

在本教程中,我将带您了解删除 Docker 镜像的不同方法,演示在删除过程中如何处理常见错误,并分享保持 Docker 环境整洁的最佳实践。

>刚接触 Docker?这份实用的容器指南能助您快速上手。

什么是 Docker 镜像?

Docker 镜像是轻量、独立、可执行的软件包,包含运行应用所需的一切——代码、运行时、库、环境变量和配置文件。

可以把它视为创建容器的快照或模板。

>Docker 不仅是软件工程师的工具——它也深受数据科学家喜爱!

Docker 镜像由多层构建,每一层都代表对文件系统的一组更改。当您从 Docker Hub 拉取镜像或使用 Dockerfile 构建镜像时,实际上是在下载或创建一组协同工作的层。层会被缓存,使镜像构建与共享更高效,但也意味着它们会占用本机存储空间。

在积极开发应用时,镜像会尤其“麻烦”。您会因为细微更改而反复重建镜像、为测试创建多个版本、拉取可能不会自动清理的依赖。

不知不觉间,几十甚至上百个镜像会吞噬大量宝贵且有限的 SSD 空间。

>如果您从事数据科学与机器学习,这 12 个 Docker 镜像一定要了解。

为什么要删除 Docker 镜像?

简单来说,Docker 镜像非常“能吃”空间,而您的磁盘空间始终有限。

删除不必要的 Docker 镜像有多重重要意义:

  • 首先,它可以回收存储空间,这对容量有限的笔记本或存储受限的 CI/CD 环境尤为关键。“设备上没有剩余空间”的错误总会在最不合时宜的时候跳出来。
  • 清理镜像还能移除过时版本,以免干扰开发或部署流程。没有什么比因为 latest 标签指向了意外版本而误用旧镜像更糟糕的了。
  • 此外,镜像列表过于杂乱会更难定位真正需要的内容。运行 docker images 时,如果屏幕上充斥着仓库、标签和 ID,要找到特定镜像就会耗时。定期清理能让您的工作环境更易管理、命令输出更易读。这种小小的体验提升长期来看很有价值。

接下来,我将展示几种删除 Docker 镜像的方式。

删除 Docker 镜像

既然您已经了解什么是 Docker 镜像以及为何要对其进行管控,让我们进入实际的删除流程。

Docker 提供了多条命令,帮助您管理镜像,从列出已有镜像到删除不需要的镜像。

查看现有 Docker 镜像

在开始删除镜像之前,您需要知道系统上究竟是什么在占空间。docker images 命令是清理流程的第一步。

docker images

该命令会列出所有 Docker 镜像及以下关键信息:

  • 仓库名(Repository)
  • 标签(Tag)
  • 镜像 ID
  • 创建日期
  • 大小

图 1 - 可用的 Docker 镜像

图 1 - 可用的 Docker 镜像

看看“大小”这一列会很有启发。如图 1所示,Oracle 数据库镜像占用了超过15GB!

如果您想按大小排序以找出最“吃”空间的镜像:

docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -h

图 2 - 按大小排序的可用 Docker 镜像

图 2 - 按大小排序的可用 Docker 镜像

这个视图更为紧凑,因为它不包含所有镜像属性。

删除特定 Docker 镜像

确定了不需要的镜像后,您可以使用 docker rmi 命令逐个删除(rmi 即“remove image”的缩写)。

您可以通过镜像 ID,或“仓库:标签”的组合来删除镜像:

# 通过镜像 ID 删除
docker rmi 4e7024df2f20

# 通过 仓库:标签 删除
docker rmi nginx:latest

图 3 - 删除单个 Docker 镜像的两种方式

图 3 - 删除单个 Docker 镜像的两种方式

还需要指出的是,Docker 不允许删除当前被容器使用的镜像。您会看到如下错误信息:

图 4 - 尝试删除正在使用中的 Docker 镜像

图 4 - 尝试删除正在使用中的 Docker 镜像

如遇此情况,您需要先停止并删除依赖的容器,再删除镜像,或者使用强制选项(稍后会介绍)。

删除多个 Docker 镜像

逐个删除镜像会很繁琐,尤其是在大规模清理时。幸运的是,Docker 支持通过一条命令删除多个镜像。

您可以提供以空格分隔的镜像列表:

docker rmi postgres:latest mariadb:latest

图 5 - 删除多个 Docker 镜像

图 5 - 删除多个 Docker 镜像

或者,在更高级的场景下,您可以结合 docker images 的过滤与管道。例如,以下命令会删除所有带有 latest 标签的镜像:

docker rmi $(docker images --filter=reference="*:latest" -q)

图 6 - 删除具有特定标签的所有 Docker 镜像

图 6 - 删除具有特定标签的所有 Docker 镜像

当然,正在被运行中的容器使用的镜像除外。

使用这些批量删除命令时请务必小心,因为它们不会要求确认。按下回车前请务必检查过滤条件。

删除悬空与未使用镜像

当您重建镜像时,Docker 会为变更部分创建新层,并复用未变部分的缓存层。先前版本中独有的层会变成“悬空(dangling)”——它们仍存在于磁盘上,但不属于任何已命名镜像。

您可以用以下命令识别悬空镜像:

docker images -f "dangling=true"

图 7 - 列出悬空的 Docker 镜像

图 7 - 列出悬空的 Docker 镜像

现在,运行 prune 命令一次性删除它们:

docker image prune

图 8 - 清理 Docker 镜像

图 8 - 清理 Docker 镜像

该命令会在执行前提示确认。如果您确定要全部删除:

docker image prune -f

若要更激进地清理,既删除悬空镜像又删除未使用(未被任何容器使用)的镜像:

docker image prune -a

图 9 - 删除所有未使用的镜像

图 9 - 删除所有未使用的镜像

最后这个命令可以释放大量空间,但请谨慎使用,因为它会删除所有未被运行或已停止容器引用的镜像。

>Docker Prune 命令到底是什么?我们专门写了篇详细文章——包含大量示例。

现在您已掌握删除 Docker 镜像的方法,接下来看看常见错误及其处理方式。

处理删除 Docker 镜像时的错误

和软件开发中的其他事情一样,删除 Docker 镜像时有时也会遇到错误。

大多数错误都有合理原因——Docker 的保护机制旨在防止您意外破坏重要内容。下面来看看常见错误及其应对方法。

错误:镜像正被容器使用

最常见的错误大致如下:

Error response from daemon: conflict: unable to delete 64ba095c0f0e (cannot be forced) - image is being used by running container 0284660ca006

这是因为 Docker 的架构对容器与镜像有严格的依赖关系。容器本质上是镜像的运行实例,并在其上方拥有可写层。

为什么 Docker 会阻止删除?很简单——如果在基于该镜像的容器仍在运行时删除镜像,容器会立刻崩溃。即便是已停止的容器也会保留对其父镜像的引用,因为它们可能会被再次启动。

要删除这类镜像,先列出所有(包括已停止的)使用该镜像的容器:

docker ps -a --filter ancestor=64ba095c0f0e

图 10 - 所有使用该镜像的容器

图 10 - 所有使用该镜像的容器

然后,停止所有这些容器:

docker stop 0284660ca006

图 11 - 停止容器

图 11 - 停止容器

接下来,删除已停止的容器:

docker rm 0284660ca006

图 12 - 删除容器

图 12 - 删除容器

最后,使用熟悉的 rmi 命令删除镜像:

docker rmi 64ba095c0f0e

图 13 - 删除 Docker 镜像

图 13 - 删除 Docker 镜像

或者,如果您偏好单条 Shell 命令,可以使用:

docker ps -a --filter ancestor=090040f97aa1 -q | xargs docker rm -f && docker rmi 090040f97aa1

图 14 - 用一条 Shell 命令完成所有步骤

图 14 - 用一条 Shell 命令完成所有步骤

是不是更简单了?

强制删除 Docker 镜像

如果您完全确定要不顾依赖地删除镜像,Docker 提供了 -f 或 --force 标志:

docker rmi -f 64ba095c0f0e

图 15 - 强制删除 Docker 镜像

图 15 - 强制删除 Docker 镜像

强制选项会让 Docker 即使在镜像被容器或其他镜像引用时也将其删除。

然而,它不会删除被正在运行的容器引用的镜像。

强制删除应作为最后手段,比如在调试 Docker 本身,或在您完全确定可以安全打破依赖时。在生产环境中,它几乎从来不是正确选择。

请记住,Docker 的依赖管控自有其道理。顺势而为而非对抗,才能获得更稳定、可预测的 Docker 体验。

管理 Docker 镜像的最佳实践

管理 Docker 镜像并非一次性任务——而是持续的日常工作。

建立良好习惯并遵循最佳实践,能避免当磁盘空间突然清零时的紧急清理。在本节中,我将介绍一些策略,帮助您维护一个干净的 Docker 环境。

>想要系统学习 Docker?我们的数据专业人士指南是一个不错的起点。

定期清理

就像不会让餐具在水槽里堆上几周一样,您也不该让未使用的 Docker 镜像无限期地堆积在系统中。

制定定期维护计划是防止镜像膨胀的最简单方法。根据您使用 Docker 的活跃程度,周期可以是每周、每月或每季度。

在清理过程中,您应当:

  1. 使用 docker images 查看镜像并确定删除候选项。
  2. 检查不熟悉或近期未使用的镜像。
  3. 查找同一应用的重复版本。
  4. 使用前述命令删除不必要的镜像。

许多开发团队也会在 CI/CD 流水线中集成镜像清理。例如,您可以配置 Jenkins 或 GitHub Actions 自动清理超过一定时长的构建镜像。

以下命令仅显示创建于 30 天之前的镜像:

docker images --format "{{.ID}}\t{{.CreatedAt}}" | awk '$2 < "'$(date -d '30 days ago' +'%Y-%m-%d')'"' | cut -f1

使用 Docker 镜像清理(pruning)

Docker 提供内置的清理命令,可将大量手动清理工作自动化。

docker system prune 会一次性删除所有已停止的容器、悬空镜像和未使用的网络:

docker system prune

若要更激进地清理并删除未使用的镜像:

docker system prune -a

您甚至可以回收构建缓存占用的空间:

docker builder prune

这些命令非常适合脚本化。下面是一个可定期运行的清理脚本示例:

#!/bin/bash
# 停止所有容器
docker stop $(docker ps -q)

# 删除所有已停止的容器
docker container prune -f

# 删除所有未使用的镜像
docker image prune -a -f

# 显示剩余磁盘用量
docker system df

图 16 - 自动化的 Docker 清理脚本

图 16 - 自动化的 Docker 清理脚本

请记住,在自动化脚本中谨慎使用 -f 标志,因为它会跳过确认提示。

保持镜像版本有序

良好的标签策略有助于减少不必要的 Docker 镜像堆积。

与其总是使用会随时间变得含糊的 latest,不如考虑以下做法:

  • 使用语义化版本为镜像打标签:
myapp:1.0.0
myapp:1.0.1
myapp:1.1.0
  • 在标签中加入构建信息:
myapp:build-2025-04-06
myapp:commit-a7f3d9e
  • 添加环境或用途限定:
myapp:1.0.0-dev
myapp:1.0.0-test
myapp:1.0.0-prod

对于较大的团队,可考虑实施镜像仓库策略,在一定期限后自动对旧镜像进行垃圾回收。Docker Hub 以及 Harbor 等私有仓库都提供镜像生命周期管理功能。

结合这些最佳实践——定期清理、自动化修剪以及有序的标签策略,您就能维持更健康的 Docker 环境,避免恼人的“设备上没有剩余空间”错误。

Docker 镜像删除总结

如果您是使用容器的开发者,妥善管理 Docker 镜像是一项必备技能。

请记住,Docker 的强大之处在于其高效隔离与打包应用的能力,但如果缺乏维护,这一优势很快会变成劣势。

您已经了解了为何 Docker 镜像会随着时间推移变得麻烦,占用宝贵磁盘空间并使开发环境凌乱。您也已掌握用于检查与删除镜像的多种命令,从使用 docker rmi 精确删除,到通过修剪命令进行批量清理。此外,您还了解了删除过程中常见错误及其应对方法。

若想进一步学习 Docker 与容器化,以下课程值得一试:

FAQs

删除 Docker 镜像后还能恢复吗?

不能。使用 docker rmi 删除 Docker 镜像后,除非您有备份或能从镜像仓库重新拉取,否则无法恢复。尤其在生产环境中,请务必确认要删除的镜像无误。对于您在本地构建的镜像,可能需要基于 Dockerfile 重新构建。

什么是悬空(dangling)Docker 镜像?如何删除?

悬空镜像是指不属于任何已打标签镜像的层,通常在多次重建镜像时产生。可通过 docker images -f "dangling=true" 识别,并用 docker image prune 一次性删除。

如何快速释放 Docker 占用的空间?

最快的释放空间方式是使用 docker system prune -a,它会删除所有已停止的容器、未使用的网络、悬空镜像以及未使用的镜像。请谨慎操作,因为它会删除未被任何容器使用的所有镜像。

我应该多久清理一次 Docker 镜像?

频率取决于您使用 Docker 的活跃程度。对于频繁构建镜像的开发环境,建议每周清理;对于不那么活跃的系统,每月或每季度维护一次即可。建议设置自动清理脚本以保持一致性。

删除与修剪 Docker 镜像有何区别?

删除是针对您选择的特定镜像进行移除,而修剪(prune)会根据一定规则自动清理所有未使用或悬空的镜像。

Dario Radečić

作者

Dario Radečić

常驻克罗地亚的高级数据科学家。顶级科技写作者,已发表 700 多篇文章,累计获得超过 1,000 万次阅读。著有《使用 TPOT 实现机器学习自动化》。

主题