gitlab ci清理过期构建产物需三步协同:先在.job中显式配置expire_in(如7 days),再由gitlab内置定时服务(每小时)扫描并物理删除,最后可手动清理孤儿制品释放空间。

GitLab CI 清理过期构建产物不是“配置完就自动删”,而是靠 配置标记 + 后台定时扫描 + 按规则执行物理删除 三步协同完成。关键在于理解它不即时清理,而是有延迟、有依赖、有策略。
在 .gitlab-ci.yml 中为每个 job 显式设置 expire_in
这是最基础也最容易遗漏的一环。必须写在产生 artifacts 的 job 下,不能只写在全局或 stage 级别:
- 单位必须明确:用 7 days、1 hour、2 weeks 等自然单位;写成
604800(秒)易出错,不推荐 - paths 要真实存在:比如
- dist/或- coverage.xml,路径是作业工作目录下的相对路径 - 仅对成功 job 生效:失败 job 默认不存 artifacts;如需保留失败产物,加
when: always - 示例:
build:
stage: build
script: npm run build
artifacts:
paths:
- dist/
expire_in: 7 days
确认 GitLab 后台清理任务已运行
expire_in 只是打个“过期标签”,真正删文件的是 GitLab 自带的定时服务(每小时一次),不是系统 crontab:
- 登录 GitLab 服务器,执行:
sudo gitlab-ctl tail cron,看是否有类似Deleting expired job artifacts的日志 - 若无记录,检查 GitLab 版本是否 ≥ 15.0(15.0+ 基本稳定支持该功能);老版本可能需手动启用或升级
- 该服务由
gitlab-rails内置调度器驱动,无需额外安装或配置 cron 条目
手动验证或临时触发清理(运维排查用)
磁盘没释放?可能是过期未清或配置未生效。可快速定位:
- 查当前项目中尚未过期的 artifacts 总大小:
sudo gitlab-rails runner "Project.find_by_full_path('group/project').ci_job_artifacts.where('artifacts_expire_at > ?', Time.now).sum(:size)" - 查已过期但还没被清理的数量:
sudo gitlab-rails runner "Ci::JobArtifact.expired.count" - 调试时可手动触发一次清理(非日常操作):
sudo gitlab-rails runner "Ci::Cleanup::ExpiredArtifactsService.new.execute"
补充:清理“孤儿制品”释放更多空间
除了过期产物,还有大量无人引用的临时文件(比如流水线中断后残留的未关联 artifacts),它们不走 expire_in 流程,但占空间更狠:
- GitLab ≥ 14.0 执行:
sudo gitlab-rake gitlab:cleanup:orphan_job_artifacts DRY_RUN=false - 执行前建议先试运行:
sudo gitlab-rake gitlab:cleanup:orphan_job_artifacts(只预览,不删) - 这个操作 100% 安全,只删完全无关联的垃圾文件,不影响任何代码、提交记录或运行中流水线
不复杂但容易忽略。











