可使用Docker 24.0+的docker image prune --filter "until=168h"命令清理7天前创建且未被容器引用的镜像,或通过自定义脚本结合docker ps -a与时间戳判断实现精准清理。

可以使用 Docker 自带的 prune 命令配合系统定时任务(如 cron)定期清理未被容器引用、且长时间未使用的镜像。关键在于区分“不再消费”——即没有运行中或已停止容器在使用,同时满足“历史过期”条件(比如 7 天前创建或拉取的镜像),而 Docker 原生命令本身不直接支持按时间过滤镜像,需借助脚本辅助实现。
确认清理目标:哪些镜像算“过期且未消费”
Docker 的 docker image prune 默认只清理“悬空镜像(dangling)”,即没有标签、也没有容器引用的镜像。但你想要的是有标签、有历史但长期闲置的镜像(例如一个月前拉取、当前无任何容器使用)。这类镜像需手动识别:
- 列出所有镜像及其创建时间:
docker images --format "{{.ID}}\t{{.Repository}}:{{.Tag}}\t{{.CreatedSince}}" - 检查是否被任何容器(含已停止)引用:
docker ps -a --format "{{.Image}}" | sort -u - 真正“未消费” = 镜像 ID 不在上述容器镜像列表中,且创建时间早于设定阈值(如 7 天)
编写安全清理脚本(推荐 bash)
以下是一个轻量、可审计的清理脚本(保存为 /usr/local/bin/docker-prune-old.sh):
#!/bin/bash
# 清理超过 7 天未被任何容器使用的镜像(跳过 dangling 和正在使用的)
DAYS=7
THRESHOLD=$(date -d "$DAYS days ago" +%s 2>/dev/null || date -v-"$DAYS"d +%s 2>/dev/null)
<h1>获取所有容器使用的镜像 ID(含已停止)</h1><p>used_ids=$(docker ps -a --format '{{.Image}}' | xargs -r docker inspect --format='{{.Id}}' 2>/dev/null | sort -u)</p><h1>遍历本地镜像,过滤出:非 dangling、未被使用、创建时间早于阈值</h1><p>docker images --format '{{.ID}}\t{{.Repository}}:{{.Tag}}\t{{.CreatedAt}}' | while IFS=$'\t' read id repo_tag created_at; do</p><h1>跳过 dangling(repo/tag 为 <none>)</h1><p>[[ "$repo_tag" == "<none>:<none>" ]] && continue</p><h1>检查是否被容器使用</h1><p>echo "$used_ids" | grep -q "^$id$" && continue</p><h1>解析创建时间戳(Docker 输出格式类似 "2024-05-10 14:22:31 +0800 CST")</h1><p>ts=$(date -d "$created_at" +%s 2>/dev/null)
[[ -z "$ts" || "$ts" -gt "$THRESHOLD" ]] && continue
echo "Removing old unused image: $repo_tag ($id)"
docker rmi "$id" 2>/dev/null || true
done
赋予执行权限:chmod +x /usr/local/bin/docker-prune-old.sh
配置系统级定时任务(cron)
以 root 用户添加每日凌晨 2 点执行:
- 运行
sudo crontab -e - 添加一行:
0 2 * * * /usr/local/bin/docker-prune-old.sh >> /var/log/docker-prune.log 2>&1 - 日志会记录每次清理动作,便于审计和排查误删
⚠️ 注意:避免与 docker system prune -f 混用,它会一并删除构建缓存、网络、卷等,风险更高。
替代方案:用 docker image prune + 时间筛选(需 Docker 24.0+)
新版 Docker(≥24.0)支持 --filter 按创建时间过滤,更简洁:
docker image prune --filter "until=168h" --filter "label!=keep" -f
说明:
-
until=168h表示“创建时间早于 168 小时前”,即 7 天前 -
label!=keep可给重要镜像打标签(docker tag xxx xxx:latest && docker image label add keep=1 xxx)避免误删 - 该命令默认只清理“未被容器引用”的镜像,符合“不再消费”语义
同样可放入 cron 执行,无需额外脚本。
不复杂但容易忽略:务必先在测试环境验证脚本逻辑,尤其是 docker rmi 命令;生产环境建议加 --dry-run 模拟(当前原生命令暂不支持,需脚本内自行实现 echo 替代 rm)。


















