You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI执行后残留<none>标签Docker镜像占用存储如何解决

问题原因

标签为<none>的残留镜像属于悬空镜像(dangling images),产生原因是每次执行docker build时,新镜像生成后旧镜像的同名标签会被转移到新镜像上,旧镜像层就会丢失标签变成<none>;默认情况下GitLab Runner执行CI任务时,只会删除任务产生的临时容器,不会自动清理构建过程中生成的悬空镜像、未被引用的临时存储卷,长期运行就会占用大量磁盘空间。

解决方案

提供两种可落地的方案,可根据实际场景选择:

方案1:在CI流程末尾添加自动清理任务(推荐,单项目生效)

在现有流水线最后新增一个cleanup阶段,给清理任务配置when: always规则,无论前面的构建、测试任务成功、失败还是被取消,都会执行清理操作。

清理逻辑说明

  • docker image prune -f:仅删除所有标签为<none>的悬空镜像,不会影响正常打标签的业务镜像
  • 如需同时清理已退出的临时容器、未被使用的网络、无主的存储卷,可以替换为docker system prune -f --volumes
  • 如果需要保留近期构建缓存提升后续构建速度,可以添加until过滤规则,例如仅清理2小时前生成的悬空镜像:docker image prune -f --filter "until=2h"

修改后的完整.gitlab-ci.yml参考如下:

variables:
  GIT_SUBMODULE_STRATEGY: recursive

stages:
  - build
  - test
  - cleanup # 新增清理阶段,放在所有业务阶段最后

build image:
  stage: build
  image: docker:20.10.16
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker pull $CI_REGISTRY_IMAGE
    - docker build --cache-from $CI_REGISTRY_IMAGE -t $CI_REGISTRY_IMAGE .
    - docker push $CI_REGISTRY_IMAGE

run-tests:
  stage: test
  image: $CI_REGISTRY_IMAGE
  script:
    - source /app/venv/bin/activate && pytest .

# 新增清理任务
ci-job-cleanup:
  stage: cleanup
  image: docker:20.10.16
  services:
    - docker:dind
  when: always
  script:
    # 基础清理:仅删除悬空<none>镜像
    - docker image prune -f
    # 如需保留2小时内的构建缓存,用下面的命令替换上面的prune命令
    # - docker image prune -f --filter "until=2h"
    # 如需深度清理(删除停止容器、无主卷、未使用网络),替换为下面的命令
    # - docker system prune -f --volumes

方案2:配置Runner全局定期清理(所有项目生效,无需修改CI配置)

如果本地Runner承载了多个项目的CI任务,不想逐个项目修改CI配置,可以在Runner部署侧配置全局清理规则:

  • 定时任务清理(最简单)
    在运行GitLab Runner的宿主机上添加crontab定时任务,例如每天凌晨2点执行一次全量清理:
    # 编辑crontab配置
    crontab -e
    # 添加以下定时规则,每天2点清理24小时前的无用Docker资源
    0 2 * * * /usr/bin/docker system prune -f --volumes --filter "until=24h"
    
    该命令不会影响正在运行的CI任务,也不会删除带正常标签的业务镜像。
  • Runner内置清理配置
    打开Runner的配置文件config.toml(容器化部署的Runner一般挂载在宿主机/etc/gitlab-runner/config.toml路径),找到对应Runner的[runners.docker]配置段,开启自动删除临时容器参数:
    [runners.docker]
      # 每次任务结束自动删除任务关联的临时容器
      autoremove = true
      volumes = ["/cache"]
    
注意事项
  • 不建议在build阶段刚完成镜像push就立刻执行prune,提前清理可能导致后续测试阶段需要重新拉取镜像,拉长流水线运行时间
  • docker system prune默认不会删除带正常标签的镜像、正在运行的容器,常规使用不会出现误删业务资源的问题

内容的提问来源于stack exchange,提问作者Rickj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:31:10