Jenkins Build Archive 应用图标
开源 · 独立于 Jenkins · 自托管 · Docker 部署

Jenkins Build Archive

Jenkins 清理了构建记录,追溯信息还在。

独立于 Jenkins 的构建元数据归档服务:流水线结束时把 Git 分支、Commit、Docker 镜像 Tag 与 Digest 存下来, 旧的 Build Record 被清理后,依然能查到“这个镜像是哪次提交构建的”。

MIT 开源 · 面向内网 · SQLite 单文件存储

Jenkins Build Archive 构建列表:统计卡片、搜索筛选和构建记录表

构建列表(演示数据):按 Job、分支、Commit、镜像 Tag 搜索,默认只看当天。

一个只管“留底”的归档服务

Jenkins 为了省空间会清理旧构建,而排查线上问题时,恰恰需要知道某个镜像来自哪次提交。它把这些信息存到一个独立的小服务里。

定位独立于 Jenkins 的构建元数据归档,构建记录被清理后仍可追溯
记录什么Job、构建号、Git 仓库 / 分支 / Commit、Commit 作者与改动文件、Docker 镜像 Tag 与 Digest、构建结果和耗时
怎么写入流水线结束时由 Shared Library 的 buildArchive() 或一条 curl POST 过来,(jobName, buildId) 幂等
怎么查内置 Web 页面和 REST API,支持 Job / 分支 / Commit / Tag 搜索与日期筛选
技术Python + FastAPI + SQLite,Docker Compose 部署,MIT 开源

小而够用,不碍事

构建记录长期留存

Jenkins 的 Build Record 被清理后,归档里的分支、Commit 和镜像信息依然在。

Git 与 Commit 详情

记录分支、Commit SHA、提交信息、作者和改动文件,详情页一眼看全。

镜像 Tag 与 Digest

Tag 可能被覆盖,Digest 不会。同时记录两者,长期追溯才靠得住。

搜索与筛选

按 Job、分支、Commit、镜像 Tag、结果和日期筛选。列表默认显示当天,「全部历史」一键切换。

Shared Library 一行接入

在 post { always { } } 里调用 buildArchive();不想用 Shared Library,直接 curl 也行。

归档失败不影响构建

归档调用出错只打印警告,不会让流水线变红;成功或失败的构建都会入库。

保留策略与批量删除

可设置最长保留天数、每个 Job 最多保留条数;删除需要管理密码并输入确认词。

写入与管理需鉴权

写接口用 API_TOKEN,Web 管理用 ADMIN_PASSWORD;两者没配置时一律拒绝。

单容器,免运维

一个容器加一个 SQLite 文件,Docker Compose 启动;表结构自动初始化,升级只要重新构建。

三步用起来

部署归档服务

在内网服务器上用 Docker Compose 启动,配置 API_TOKEN 和管理密码。

配置 Jenkins

设置 BUILD_ARCHIVE_URL 和 Token,并把本仓库登记为名为 build-archive 的 Shared Library。

流水线里调用

在 post { always { buildArchive() } } 中调用一次,之后每次构建都会自动入库。

接入 Jenkins

推荐用 Shared Library;也可以不装库,直接在 Jenkinsfile 里 curl。

Shared Library(推荐)

先在 Manage Jenkins 里配置全局环境变量 BUILD_ARCHIVE_URL、BUILD_ARCHIVE_TOKEN,并把本仓库登记为名为 build-archive 的 Global Pipeline Library。然后:

@Library('build-archive') _

pipeline {
    agent any
    stages {
        stage('Build') {
            steps { sh 'echo build...' }
        }
    }
    post {
        always {
            buildArchive()   // 必须 always,失败的构建也会入库
        }
    }
}

Agent 需要装有 curl。

附带镜像 Tag 与 Digest

在调用 buildArchive() 前,把镜像信息放进环境变量即可:

stage('Push image') {
    steps {
        script {
            def tag = "registry.example.com/dev/my-app:${env.BUILD_NUMBER}"
            env.DOCKER_IMAGE_TAG = tag
            sh "docker build -t ${tag} . && docker push ${tag}"
            env.DOCKER_IMAGE_DIGEST = sh(
                script: "docker inspect --format='{{index .RepoDigests 0}}' ${tag} | awk -F@ '{print \$2}'",
                returnStdout: true
            ).trim()
        }
    }
}

服务不会主动去查 Registry,Digest 由流水线传入。

不用 Shared Library:直接 POST

写入接口是 POST /api/v1/builds,用 Bearer Token 鉴权,(jobName, buildId) 相同则更新。先手工验证一次:

curl -X POST http://127.0.0.1:8080/api/v1/builds \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{"jobName":"demo","buildId":1,"buildDate":"2026-08-14T10:00:00+08:00","buildResult":"SUCCESS","buildUrl":"https://jenkins.example/job/demo/1/"}'
构建详情页:构建信息、Git 信息、Commit 详情和 Docker 镜像
构建详情(演示数据):Git、Commit、镜像 Tag 与 Digest 一页看全
归档字段Jenkins 来源
jobNameJOB_NAME
buildIdBUILD_NUMBER
gitBranchGIT_BRANCH / BRANCH_NAME
gitCommitGIT_COMMIT
commitMsg / commitAuthor / commitFiles同名环境变量,或 buildArchive(...) 参数
dockerImageTag / dockerImageDigestDOCKER_IMAGE_TAG / DOCKER_IMAGE_DIGEST
buildResultcurrentBuild.currentResult
buildUrl / durationMsBUILD_URL / currentBuild.duration

REST API

读接口默认开放,写入与管理接口必须带 Bearer Token。

方法路径鉴权说明
GET/health无健康检查
GET/api/v1/stats无统计
GET/api/v1/builds无列表,支持 q / job / branch / result / dateFrom / dateTo / page / pageSize
GET/api/v1/builds/{id}无详情(含 Commit 信息)
POST/api/v1/buildsBearer创建或更新(幂等)
DELETE/api/v1/builds/{id}Bearer删除
GET/api/v1/admin/retentionBearer查看保留策略
POST/api/v1/admin/retention/runBearer立即执行清理

说明:API 列表默认不过滤日期;Web 列表默认只显示当天,访问 /?all=1 查看全部历史。

快速部署

需要一台内网服务器,装有 Docker 与 Docker Compose。数据只有一个 SQLite 文件。

  1. 获取代码

    克隆仓库并进入目录,复制环境变量模板。

    git clone https://github.com/AlexWuYh/jenkins-build-archive.git
    cd jenkins-build-archive
    cp .env.example .env
  2. 编辑配置

    把 API_TOKEN 和 ADMIN_PASSWORD 换成你自己的值,不要使用示例里的占位符。

    API_TOKEN=请替换成足够长的随机字符串
    ADMIN_PASSWORD=请设置管理密码
    TZ=Asia/Shanghai
    RETENTION_DAYS=365
    RETENTION_MAX_PER_JOB=0
  3. 启动并检查

    启动后访问健康检查接口,再用浏览器打开 http://服务器IP:8080。

    docker compose up -d --build
    curl http://127.0.0.1:8080/health
  4. 备份与升级

    数据在 ./data/build_archive.db。在线备份用 SQLite 的 backup 接口;升级则拉取新代码后重新构建,表结构会自动初始化。

    docker exec jenkins-build-archive python -c \
      "import sqlite3; s=sqlite3.connect('/data/build_archive.db'); d=sqlite3.connect('/data/backup.db'); s.backup(d); d.close(); s.close()"
    
    git pull
    docker compose up -d --build
变量含义
API_TOKEN写接口的 Bearer Token,Jenkins 侧的 BUILD_ARCHIVE_TOKEN 要与它一致
ADMIN_PASSWORDWeb 管理(删除、保留策略)的密码
TZ时区,决定列表“当天”的范围
RETENTION_DAYS最长保留天数,0 表示关闭;在 UI 保存后以数据库中的值为准
RETENTION_MAX_PER_JOB每个 Job 最多保留条数,0 表示关闭

仅限内网使用:读接口默认不需要登录,请不要把服务映射到公网,或在反向代理处限制来源。清理策略不可恢复,收紧之前先备份数据库。

完整说明见 GitHub README、 Shared Library 文档。

让每一次构建都有迹可循

免费、开源,跑在你自己的内网里。