如何完整的删除Docker镜像和容器
Docker在长期使用后会产生大量无用的镜像、容器和卷,占用宝贵的磁盘空间。 本文将系统讲解如何安全高效地清理 Docker 环境,包含基础操作、进阶技巧和注意事项。还有以在实际环境操作举例完整说明
bash# 查看所有容器(包括已停止的)
docker ps -a
# 删除单个停止的容器
docker rm <container_id>
# 批量删除所有停止的容器
docker container prune
bash# 查看所有镜像列表
docker images
# 删除单个镜像
docker rmi <image_id>
# 强制删除镜像(当有容器依赖时)
docker rmi -f <image_id>
# 删除所有悬空镜像(未被任何容器引用的中间层)
docker image prune
# 删除指定仓库的所有标签
docker rmi $(docker images <repository> --format "{{.ID}}")
bash# 删除 7 天前的镜像
docker image prune -a --filter "until=168h"
# 删除 30 天前的卷
docker volume prune --filter "until=720h"
bash# 删除指定镜像的所有标签
docker rmi $(docker images --filter=reference='<repository>:*' -q)
# 结合 grep 过滤特定镜像
docker images | grep 'nginx' | awk '{print $3}' | xargs docker rmi
# 删除所有未被使用的资源(镜像/容器/网络)
docker system prune
bash#!/bin/bash
# 一键清理脚本(慎用!)
echo "清理停止的容器..."
docker container prune -f
echo "清理无用镜像..."
docker image prune -a -f
echo "清理未使用卷..."
docker volume prune -f
echo "清理网络..."
docker network prune -f
echo "清理完成!"
docker ps -a
docker save
docker system prune --dry-run
预览删除内容资源类型 | 生命周期 | 清理命令 |
---|---|---|
容器 | 运行时存在,停止后仍保留 | docker rm |
镜像 | 由多个层组成,需手动清理 | docker rmi |
数据卷 | 持久化存储 | docker volume prune |
网络 | 自定义网络需手动管理 | docker network prune |
当出现 Error response from daemon: conflict
错误时:
bash# 查找依赖该镜像的容器
docker ps -a --filter "ancestor=<image_id>"
# 先删除相关容器
docker rm <container_id>
Docker 镜像由多层构成,可通过以下命令优化:
bash# 删除所有中间层镜像
docker builder prune
开发环境:使用 --rm
参数自动清理临时容器
bashdocker run --rm -it ubuntu /bin/bash
生产环境:
监控磁盘使用:
bashdocker system df # 查看 Docker 磁盘使用情况
假设我要删除第一项服务。以下是删除镜像 henrygd/beszel-agent:latest
的详细实战步骤,包含安全验证和容错机制
bash# 列出所有容器(包括已停止的),过滤出使用该镜像的实例
docker ps -a --filter "ancestor=henrygd/beszel-agent:latest"
情况一(无容器依赖):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
解释:没有容器使用此镜像,可直接删除。
情况二(存在容器依赖):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a1b2c3d4e5f6 henrygd/beszel-agent:latest ... 5 days ago Exited (0) 2 days ago web-server
解读:有容器依赖,需先处理容器。
bash# 停止容器(如果容器仍在运行)
docker stop a1b2c3d4e5f6
# 删除容器(替换为实际的 CONTAINER ID)
docker rm a1b2c3d4e5f6
bash# 通过镜像名直接删除所有关联容器(慎用!确保无重要数据)
docker rm $(docker ps -aq --filter "ancestor=henrygd/beszel-agent:latest")
bash# 执行删除命令
docker rmi henrygd/beszel-agent:latest
Untagged: henrygd/beszel-agent:latest Deleted: sha256:25c207be20b7...
Error response from daemon: conflict
:bashdocker rmi -f henrygd/beszel-agent:latest
bash# 再次查看镜像列表
docker images | grep "henrygd/beszel-agent"
# 预期输出:无相关镜像记录
bash# 1. 检查容器依赖
$ docker ps -a --filter "ancestor=henrygd/beszel-agent:latest"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 henrygd/beszel-agent:latest ... 5 days ago Exited (0) 2 days ago web-server
# 2. 删除关联容器
$ docker rm a1b2c3d4e5f6
a1b2c3d4e5f6
# 3. 删除镜像
$ docker rmi henrygd/beszel-agent:latest
Untagged: henrygd/beszel-agent:latest
Deleted: sha256:25c207be20b7...
# 4. 验证删除
$ docker images | grep "henrygd/beszel-agent"
# 无输出
数据安全:
docker inspect <container>
检查容器挂载的卷(Mounts
字段)。镜像别名冲突:
如果同一镜像有多个标签(如 dev
/prod
),需删除所有标签:
bashdocker rmi $(docker images --filter=reference='henrygd/beszel-agent:*' -q)
强制删除场景:
当容器处于 Exited
状态但无法删除时,使用:
bashdocker container prune --filter "until=72h" # 清理72小时前的停止容器
如果遇到这种情况,理论上不大可能,但是也会有可能遇到。
docker images
输出中显示为 <none>:<none>
。latest
)多次构建镜像,旧镜像会被覆盖标签,变成无主状态。dangling=true
?dangling
(悬空状态)。dangling=true
:相当于用过滤器快速找到这些“空白占位图”,方便你一键清理。从实战输出可以看到,原本的镜像 henrygd/beszel-agent:latest
已经变成 <none>:<none>
,这说明它已经成为 悬空镜像(Dangling Image)。这种情况通常发生在以下场景:
docker build -t henrygd/beszel-agent:latest .
)以下是针对悬空镜像的 完整清理方案:
bash# 查看所有悬空镜像(无仓库名和标签)
docker images -f "dangling=true"
# 输出示例:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 25c207be20b7 9 days ago 7.85MB
bash# 通过 IMAGE ID 直接删除
docker rmi 25c207be20b7
Error response from daemon: conflict: unable to delete 25c207be20b7 (must be forced) - image is referenced in multiple repositories
bashdocker rmi -f 25c207be20b7
bash# 删除所有悬空镜像(推荐)
docker image prune
# 输入 y 确认删除
# 输出示例:
Deleted Images:
deleted: sha256:25c207be20b7...
Total deleted: 7.85MB
如果上述操作后仍有残留,使用以下命令清理 所有未被使用的镜像层:
bash# 删除所有未被容器或新镜像引用的镜像层
docker builder prune --all
# 或者结合强制删除
docker system prune -a --volumes
概念 | 说明 |
---|---|
悬空镜像 | 被其他镜像覆盖标签后遗留的中间层镜像,无实际仓库名和标签 |
中间层镜像 | Docker 镜像由多层文件系统组成,构建新镜像时会生成新的中间层 |
镜像引用关系 | 一个镜像可能被多个标签或容器引用,只有所有引用解除后才能彻底删除 |
bash# 1. 查看悬空镜像
$ docker images -f "dangling=true"
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 25c207be20b7 9 days ago 7.85MB
# 2. 删除单个悬空镜像
$ docker rmi 25c207be20b7
Error response from daemon: conflict: unable to delete 25c207be20b7 (must be forced) - image is referenced in multiple repositories
# 3. 强制删除(如果普通删除失败)
$ docker rmi -f 25c207be20b7
Untagged: 25c207be20b7...
# 4. 批量清理验证
$ docker image prune
Deleted Images:
deleted: sha256:25c207be20b7...
Total deleted: 7.85MB
避免重复覆盖标签:
为不同版本的镜像使用唯一标签(例如 v1.0
、v1.1
),不要重复使用 latest
bashdocker build -t henrygd/beszel-agent:v1.0 .
定期清理:
将以下命令加入定时任务(cron):
bash# 每天凌晨清理悬空镜像
0 3 * * * docker image prune -f
使用镜像管理工具:
推荐使用 dive
工具分析镜像层:
bashdive henrygd/beszel-agent:latest
有时候你跟着步骤做的操作步骤是对的。但还是删除镜像 25c207be20b7
失败。
失败的原因是:该镜像被一个名为 ba698fd40eb0
的容器引用,但该容器可能已被删除或处于异常状态。以下是具体原因和解决方案:
容器与镜像的依赖关系
镜像 25c207be20b7
被容器 ba698fd40eb0
使用,但:
25c207be20b7
)作为容器ID,导致操作失败。ba698fd40eb0
,需要针对该容器操作。镜像被中间层引用
该镜像可能是其他镜像的构建中间层,即使没有显式容器依赖,也可能被 Docker 内部引用。
bash# 1. 查找使用该镜像的容器(包括已停止的)
docker ps -a --filter "ancestor=25c207be20b7"
# 2. 删除关联容器(替换为实际的 CONTAINER ID)
docker rm -f ba698fd40eb0 # 强制删除容器(即使已停止)
# 3. 再次删除镜像
docker rmi 25c207be20b7
如果确认无重要容器依赖,可直接清理所有悬空镜像:
bash# 1. 批量删除所有悬空镜像
docker image prune -f
# 2. 深度清理(含中间层缓存)
docker builder prune --all
如果仍报错,检查镜像是否被其他标签或构建缓存引用:
bash# 查看镜像的引用关系
docker image inspect 25c207be20b7 --format='{{.RootFS.DiffIDs}}'
# 清理所有未被引用的镜像层
docker system prune -a --volumes
bash# 1. 确认容器已删除
docker ps -a | grep "ba698fd40eb0"
# 2. 确认镜像已删除
docker images | grep "25c207be20b7"
清理 Docker 镜像和容器的核心命令与注意事项
docker container prune
(批量删停止的容器);docker image prune
(删悬空镜像),docker rmi <image_id>
(指定镜像);dangling=true
过滤,普通删除或强制 docker rmi -f
;docker ps -a
),避免强制误删,生产环境慎用 docker system prune
。-f
参数会跳过依赖检查,确保无重要数据后再使用。本文作者:Dageling003
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!