docker rmi 本身不支持按创建时间过滤,必须结合 docker images 输出与时间解析实现:先用 --format 提取 ID 和时间(新版用 {{.CreatedAt}},旧版需 inspect),再转为 Unix 时间戳比较,最后用 awk/Python 等安全筛选并强制删除。

docker rmi 怎么按创建时间清理旧镜像
直接说结论:docker rmi 本身不支持按时间过滤,必须靠 docker images 输出 + 时间解析组合实现。别指望一条命令搞定,这是运维里高频踩坑点。
常见错误是想当然用 docker rmi $(docker images --format "{{.ID}}" --filter "before=xxx") —— --filter before 只认镜像名或 ID,不认时间戳,这么写根本不会生效。
实操建议:
- 用
docker images --format "{{.ID}}\t{{.CreatedAt}}"提取镜像 ID 和创建时间(注意:{{.CreatedAt}}是 Docker 20.10+ 才支持的字段,老版本得用docker image inspect -f '{{.Created}}'逐个查) - 时间比较必须转成 Unix 时间戳,否则字符串比大小会出错(比如
"2023-01-10">"2023-09-01") - 推荐用
awk或python -c做时间判断,避免 shell 内置 date 命令在不同系统上行为不一致
Shell 脚本清理 30 天前的 dangling 镜像
真正安全、可落地的清理,往往不是删所有旧镜像,而是先清 的 dangling 镜像(构建残留、未打标签的中间层),再按需处理带名镜像。
这类操作最容易被忽略的是:没加 --force 时,docker rmi 遇到被容器引用的镜像会报错退出,导致后续镜像全卡住不删。
实操建议:
- 先跑
docker images -f "dangling=true" -q拿到所有 dangling ID - 用
xargs -r docker rmi -f强制删除(-r防空输入报错) - 不要把
docker rmi和docker images管道直连,万一某条rmi失败,整个管道就中断;用循环 +|| true更稳
Python 脚本精准删除指定天数前的非 dangling 镜像
要删带名字、有标签的旧镜像,就得自己解析时间。Shell 处理日期太脆弱,尤其跨平台时 date -d 在 macOS 不可用,这时候 Python 是更可靠的选择。
关键点在于:Docker 返回的 {{.CreatedAt}} 是 ISO8601 格式(如 2023-04-12 15:23:41 +0800 CST),但 Python 的 datetime.fromisoformat() 不支持时区缩写(CST),得用 dateutil.parser.parse() 或正则截掉时区部分。
实操建议:
- 用
subprocess.run(["docker", "images", "--format", "{{.ID}}\t{{.CreatedAt}}\t{{.Repository}}:{{.Tag}}"], capture_output=True, text=True)获取原始数据 - 对每行做
parser.parse(created_at_str).timestamp() 判断 - 过滤掉
(即 dangling)再删,避免重复清理: - 删之前
print出镜像名和时间,人工确认无误再执行docker rmi
为什么 docker system prune 不适合定时清理生产镜像
docker system prune -a --force 看似省事,但它会删掉所有未被容器引用的镜像,不管新旧 —— 这在 CI/CD 频繁构建的环境里,可能刚拉下来的新基础镜像下一秒就被清掉,导致构建失败。
更隐蔽的问题是:它不区分 build cache 和真实镜像,而 docker buildx build --cache-to 产生的缓存镜像也会被一锅端,破坏增量构建链路。
实操建议:
- 禁用
--all参数,只用docker system prune --force清网络、卷、构建缓存(默认不删镜像) - 生产环境定时任务里,绝不要混用
prune和手动rmi,两者底层锁机制不同,可能引发graph driver错误 - 如果用了
overlay2,注意docker rmi删除后磁盘空间不会立刻释放,得等内核回收,监控要用du -sh /var/lib/docker/overlay2而不是df
时间字段的模糊性最麻烦:Docker 的 CreatedAt 是镜像层首次生成时间,不是 docker pull 时间,也不是你本地 docker build 完成时间。同一镜像在不同节点上看到的“创建时间”可能差几天,别拿它当绝对依据。










