Bencher v0.6.13 配置参数详解

Bencher v0.6.13 API Server JSON 配置(bencher.json)9 个顶层域 + Console 环境变量完整字段表:security/server/logging/database/smtp/plus.*,附最小化单节点与 Plus 版企业级两套生产模板。

BencherBencherRust语言DevOps工程CI性能基准REST2026/10/27

Bencher v0.6.13 配置参数详解

目标:完整梳理 Bencher v0.6.13 自托管版的 API Server JSON 配置(bencher.json)和 Console Server 环境变量两个入口,按功能域分类详解每个字段的作用、默认值、必填性、生产推荐值与踩坑清单,并附两套生产配置模板(最小化单节点 + Plus 版企业级)。

一、环境信息

项值
Bencherv0.6.13(2026-09-28)
API Server 配置文件位置容器内 /etc/bencher/bencher.json
API Server 配置环境变量BENCHER_CONFIG_PATH / BENCHER_CONFIG
Console Server 配置入口容器环境变量(无 JSON 文件)
配置加载优先级API:BENCHER_CONFIG 环境变量(内联 JSON) > BENCHER_CONFIG_PATH(文件路径) > /etc/bencher/bencher.json > 内置默认值;Console:纯环境变量,无优先级链
查询日期2026-10-27

二、前置条件

  • 已完成 B1/B2 部署,API Server 和 Console 容器正常运行
  • 有权进入容器查看/修改 /etc/bencher/bencher.json(或通过 bind mount 改宿主机的 etc/ 目录)
# 查看容器内实际生效配置(敏感值会打码)
curl -s http://localhost:6610/v0/server/config \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${BENCHER_API_KEY}" | python3 -m json.tool

三、参数查看与修改方式

3.1 查看当前生效配置

# 需要服务端管理员权限(首次安装默认有)
BENCHER_API_KEY="$(bencher user key --token 你的管理员用户名 2>/dev/null | awk '{print $NF}')"
curl -s -H "Authorization: Bearer $BENCHER_API_KEY" http://localhost:6610/v0/server/config | python3 -m json.tool
# 返回值中敏感字段自动打码(如 secret_key → ************)

3.2 修改配置的两种方式

方式 1:修改宿主机 bind mount 的 services/api/etc/bencher.json → 重启容器

# 编辑
vim /opt/bencher-stack/services/api/etc/bencher.json

# 重启 API 容器
docker compose -p bencher-0613-stack restart bencher_api_compose

适合生产环境,改动持久化到数据目录。

方式 2:CLI 直接传递环境变量(适合快速试验)

bencher up --detach \
  --api-env 'BENCHER_CONFIG={"database":{"cache_size":131072}}' \
  --api-volume '/opt/bencher-stack/services/api/etc:/etc/bencher'

注意:--api-env 每次 bencher up 都会重新注入,--api-volume 只在显式传才挂。

四、参数总览

Bencher 的配置分两大类、九个顶层域:

域位置作用
consoleAPI Server JSON告诉 API Server Console URL(用于 Email 链接、SAML 回调等)
securityAPI Server JSONJWT issuer + secret_key(必改)
serverAPI Server JSON监听地址、请求体限制、TLS
loggingAPI Server JSON日志级别与输出方式(stderr / file)
databaseAPI Server JSONSQLite 文件路径、busy_timeout、cache_size
smtpAPI Server JSON邮件发送(邀请、确认密码重置等)
plus.*API Server JSONPlus 版:灾难恢复 / registry / runners / rate_limiting / stats / GitHub SSO / Google SSO
Console env vars容器 environment:BENCHER_API_URL / INTERNAL_API_URL / SERVER_KEY_PATH / SERVER_CERT_PATH

五、核心参数分类详解

5.1 console 域

告诉 API Server Console 的 URL,用于在 Email、OAuth 回调、CLI 输出链接中拼接完整路径。

字段类型默认必填说明
urlstringhttp://localhost:3000✅Console 公开可访问的 URL。如果 Console 走外层 nginx(HTTPS),这里必须改成 https://bencher.example.com,否则 OAuth/SAML callback 会回环失败、Email 链接是 localhost。

⚠️ 踩坑:console.url 与 Console 容器的 BENCHER_API_URL 不是同一个东西!前者是 API Server 向外输出 Console URL 的配置;后者是 Console 前端调 API 的地址。走反代时两边都要配对。

5.2 security 域(必改)

JWT 和敏感操作签名的密钥域。首次启动默认会自动生成一个 UUID v4 作为 secret_key,但生产环境强烈建议显式设置并妥善保管。

字段类型默认必填说明
issuerstringbencher.dev❌JWT 的 iss claim。⚠️ 一旦改了,所有已发 JWT 立即失效——用户需要重新登录、runner 需要重建 key、CI 的 BENCHER_API_KEY 需要重置。
secret_keystring自动生成 UUID v4✅JWT 签名和 callback 加密密钥。日志里会打码为 ************。丢了 = 所有 token 失效,备份好!

5.3 server 域

Dropshot HTTP 框架(oxidecomputer/dropshot)原生配置。

字段类型默认必填说明
bind_addressstring0.0.0.0:6610✅API Server 监听地址。生产环境如果只走外层反代,可以改成 127.0.0.1:6610 拒绝直连。
request_body_max_bytesint1048576(1 MB)✅单次 run POST 请求体上限。bencher run 上传 benchmark 结果(BMF 格式 JSON),如果单个项目 benchmark 数量很多,默认 1 MB 可能不够 → 改成 10485760(10 MB)。
tls.typestring不设置❌"as_file" 或 "as_bytes"。不推荐 API Server 自配 TLS——让外层 nginx 承担,API 保持 HTTP 到 localhost 即可。
tls.cert_file / tls.key_filestring—条件仅当 tls.type=as_file 时需要。

5.4 logging 域

字段类型默认必填说明
namestring"Bencher API"✅日志中的 logger 名称前缀
log.levelstring"info"✅日志级别:trace / debug / info / warn / error / critical(从低到高)。生产推荐 info;排障可临时开 debug。
log.modestring"stderr_terminal"❌"stderr_terminal"(输出到 stderr,docker logs 可见)或 "file"(落盘文件)。容器化部署默认 stderr_terminal 就对了。
log.pathstring—条件仅 log.mode=file 时需要。
log.if_existsstring—条件仅 log.mode=file 时。append / truncate / fail。

5.5 database 域(SQLite)

这是最容易被忽视但对性能影响最大的域——SQLite WAL 模式下 cache_size 决定了大报告 ingest 的速度,busy_timeout 决定锁冲突是否会演变成 500 错误。

字段类型默认必填说明
filestring/var/lib/bencher/data/bencher.db✅SQLite 文件路径。compose 里挂到 /var/lib/bencher/data 就指向宿主机 bind mount。
busy_timeoutint5000(5 秒)❌SQLITE_BUSY 等待毫秒数。并发 run 多的时候 5s 不够,生产推荐 15000。
cache_sizeint65536(约 64 MiB)❌WAL writer 连接的页缓存大小(KiB)。大报告 ingest 时需要足够大避免重复读——生产推荐 131072(128 MiB),内存充裕可以到 262144。必须 > 0。

💡 cache_size 单位是 KiB,别搞错——65536 ≈ 64 MiB。如果你设成 1024 那才 1 MiB,完全不够。

5.6 smtp 域(可选)

不配 SMTP 时,所有 Email 会被打到日志里(stderr)——开发/PoC 阶段够用,生产必须配。

字段类型默认必填说明
hostnamestring—✅(配 SMTP 时)SMTP 服务器地址
portint587❌通常 587(STARTTLS)或 465(SSL)
insecure_hostboolfalse❌允许自签/过期 TLS 证书(生产别开)
starttlsbooltrue❌用 STARTTLS 升级加密(配 587 时必须 true)
usernamestring—✅(配 SMTP 时)邮箱账号
secretstring—✅(配 SMTP 时)邮箱密码或应用专用密码。日志里打码。
from_namestring—✅(配 SMTP 时)发件人显示名称(如 "Bencher CI")
from_emailstring—✅(配 SMTP 时)发件邮箱地址

5.7 plus.* 域(Plus 版才有的功能)

plus 下有六个子域,全部归 Bencher Plus 商业许可所有。免费自托管版可以留空——API Server 正常启动、对应功能返回 403。

5.7.1 plus.disaster_recovery(Litestream → S3 连续复制)

Bencher 用 Litestream 在后台持续把 SQLite WAL 帧复制到目标存储,这是免费版没有的唯一数据可靠性方案。支持 file(本地复制路径)或 s3(S3 兼容对象存储)两种 scheme。

"plus": {
  "disaster_recovery": {
    "replica": {
      "scheme": "s3",
      "bucket": "bencher-backup",
      "path": "prod/",
      "endpoint": "https://s3.amazonaws.com",
      "region": "auto",
      "access_key_id": "${S3_ACCESS_KEY}",
      "secret_access_key": "${S3_SECRET_KEY}"
    },
    "snapshot": {
      "interval": "1h",
      "retention": "24h"
    },
    "checkpoint": {
      "interval": "1m",
      "min_page_count": 1000,
      "truncate_page_n": 0
    }
  }
}
字段默认说明
replica.scheme—"file" 或 "s3",选其一
snapshot.interval不设(每天一次)多久生成一次新快照,减少 restore 时间
snapshot.retention"24h"快照 + WAL 保留多久
checkpoint.interval"1m"非阻塞 PASSIVE checkpoint 周期
checkpoint.min_page_count1000(约 4 MB)WAL 页数量阈值
checkpoint.truncate_page_n0(禁用)阻塞 TRUNCATE checkpoint 阈值。非 0 会阻塞写操作,生产别开。

5.7.2 plus.registry(Bencher 作为 OCI Registry)

Bencher API Server 内置一个符合 OCI v2 规范的容器镜像仓库——bare metal runner 的 benchmark 环境镜像可以存这里。默认用本地文件系统存储(适合单节点),生产用 S3。

"plus": {
  "registry": {
    "url": "https://registry.bencher.example.com",
    "storage": {
      "scheme": "file",
      "path": "registry"
    },
    "upload_timeout": 3600,
    "max_body_size": 1073741824
  }
}
字段默认说明
storage.scheme"file""file" 本地 FS 或 "s3"
storage.chunk_size5242880(5 MiB)分片上传大小
upload_timeout3600(秒)镜像上传超时
max_body_size1073741824(1 GiB)Registry 单请求上限

5.7.3 plus.runners

控制 bare metal runner 的心跳与 job 超时:

字段默认说明
heartbeat_timeout90 秒runner 心跳超时,超时即标记 offline
job_timeout_grace_period60 秒runner job 超时宽限期
update_base_urlGitHub Releases 下载 URLrunner 自更新时下载二进制的基地址

5.7.4 plus.rate_limiting

完整的速率限制配置,分 public / user / project / runner 四档,每档又分 requests(每秒/每小时/每天)、attempts、credentials、organizations、invites、runs 六类。生产如果是公开 Cloud 端点,建议把 public.requests.minute 降到 512、public.runs.minute 降到 32 防刷。

5.7.5 plus.github / plus.google(SSO OAuth)

Plus Enterprise 版的 SSO,需要先在 GitHub/Google 平台创建 OAuth App 拿到 client_id 和 client_secret。

5.8 Console Server 环境变量

Console Server 是 Next.js 静态前端,没有 JSON 配置——全部通过容器环境变量控制:

变量默认必填说明
BENCHER_API_URLhttp://localhost:6610✅(生产必改)浏览器端调 API 的地址。如果外层有 nginx 反代,填 https://bencher.example.com
INTERNAL_API_URL不设置条件只在 Docker 内部网络通信时需要,指向 API 容器名:http://bencher_api_compose:6610。走外部 API(如 Cloud)时不要设这个。
SERVER_KEY_PATH无❌Console 自配 TLS(不推荐)
SERVER_CERT_PATH无❌Console 自配 TLS(不推荐)
OAUTH_GITHUB不设置❌Plus Enterprise 版开关,设为 "true"
OAUTH_GOOGLE不设置❌Plus Enterprise 版开关,设为 "true"

六、生产配置模板

6.1 模板 A:最小化单节点自托管(4 核 8 GB)

无 Plus 功能、外层 nginx 做 HTTPS、SQLite cache_size 翻倍:

{
  "console": {
    "url": "https://bencher.example.com"
  },
  "security": {
    "issuer": "https://bencher.example.com",
    "secret_key": "请替换为你自己的 UUID v4 —— 备份好"
  },
  "server": {
    "bind_address": "0.0.0.0:6610",
    "request_body_max_bytes": 10485760
  },
  "logging": {
    "name": "Bencher API",
    "log": {
      "stderr_terminal": {
        "level": "info"
      }
    }
  },
  "database": {
    "file": "/var/lib/bencher/data/bencher.db",
    "busy_timeout": 15000,
    "cache_size": 131072
  }
}

Console 容器 environment:

environment:
  - BENCHER_API_URL=https://bencher.example.com   # 外层反代 URL
  - INTERNAL_API_URL=http://bencher_api_compose:6610

6.2 模板 B:Plus 版企业级(多节点 + S3 + Litestream + SSO)

{
  "console": {
    "url": "https://bencher.example.com"
  },
  "security": {
    "issuer": "https://api.bencher.example.com",
    "secret_key": "请替换并备份"
  },
  "server": {
    "bind_address": "0.0.0.0:6610",
    "request_body_max_bytes": 52428800
  },
  "logging": {
    "name": "Bencher API",
    "log": {
      "stderr_terminal": {
        "level": "info"
      }
    }
  },
  "database": {
    "file": "/var/lib/bencher/data/bencher.db",
    "busy_timeout": 30000,
    "cache_size": 262144
  },
  "smtp": {
    "hostname": "smtp.example.com",
    "port": 587,
    "starttls": true,
    "username": "bencher@example.com",
    "secret": "${SMTP_APP_PASSWORD}",
    "from_name": "Bencher CI",
    "from_email": "bencher@example.com"
  },
  "plus": {
    "disaster_recovery": {
      "replica": {
        "scheme": "s3",
        "bucket": "bencher-dr-backup",
        "path": "prod/",
        "endpoint": "https://s3.amazonaws.com",
        "region": "auto",
        "access_key_id": "${S3_ACCESS_KEY}",
        "secret_access_key": "${S3_SECRET_KEY}"
      },
      "snapshot": { "interval": "1h", "retention": "24h" },
      "checkpoint": { "interval": "1m", "min_page_count": 1000 }
    },
    "registry": {
      "url": "https://registry.bencher.example.com",
      "storage": {
        "scheme": "s3",
        "bucket": "bencher-registry",
        "path": "images/",
        "endpoint": "https://s3.amazonaws.com",
        "region": "auto",
        "access_key_id": "${S3_ACCESS_KEY}",
        "secret_access_key": "${S3_SECRET_KEY}",
        "chunk_size": 10485760
      },
      "upload_timeout": 3600,
      "max_body_size": 2147483648
    },
    "runners": {
      "heartbeat_timeout": 90,
      "job_timeout_grace_period": 60
    },
    "github": {
      "client_id": "${GITHUB_CLIENT_ID}",
      "client_secret": "${GITHUB_CLIENT_SECRET}"
    }
  }
}

七、常见问题

Q1:改了 security.issuer 之后所有用户登不上了?

这是预期行为——issuer 是 JWT payload 的 iss claim,改了之后服务端验证 JWT 时会把老 token 的 iss 拒掉。不要在运行中改 issuer,如果必须改,通知所有用户重新登录、重建所有 runner key、重建所有 project API key。

Q2:API Server 日志里满屏 "database is locked"?

三个地方要调:

  1. busy_timeout 调到 15000 以上;
  2. cache_size 调到 131072;
  3. 并发写入 QPS 太高的话,Plus 版可以开 checkpoint.truncate_page_n 但会阻塞写操作,谨慎。

Q3:request_body_max_bytes 设成 10MB 了还报 400?

检查外层 nginx/caddy 是否有自己的 body size 限制——nginx 默认 client_max_body_size 1m,需要在反代 location 里显式调大。

Q4:Console 打开后 JS 报错 401/跨域错误?

大概率是 BENCHER_API_URL 填成了 http://localhost:6610 但浏览器从 https://bencher.example.com 打开 Console——跨域了。改成浏览器能直接访问的地址(和 Console 同域名或同协议)。

Q5:plus. 功能免费版能开吗?*

不能。免费版自托管 API Server 代码里会校验 Plus license key,没有的话直接 403。如果你的场景里不需要 Litestream / SSO / Registry S3,别配 plus 域,留空即可。

八、参考链接