PushBits 0.10.7 配置参数详解

逐段拆解 PushBits 0.10.7 全部配置项:config.yml 与 PUSHBITS_ 环境变量的加载优先级、官方镜像软链布局与内置默认值、数组参数环境变量写法、Alertmanager 注解键自定义与修复行为实测,全部结论经 Compose+自建 Synapse 环境实测背书。

PushBitsPushBits配置参数详解Matrix配置自托管2026/10/26

PushBits 0.10.7 配置参数详解

目标:逐段拆解 PushBits 0.10.7 的全部配置项——配置加载机制(config.yml 与环境变量的优先级)、官方镜像的软链布局与内置默认值、数组型参数的环境变量写法、以及 Alertmanager 注解键自定义等进阶行为。全部结论均在 Docker Compose(PushBits 0.10.7 + 自建 Synapse homeserver)环境中实测验证,命令与回显皆为真实记录。

一、实验环境与本篇定位

本篇是专栏的配置参考篇:《Ubuntu 22.04 安装指南》已给出最小可用 config.yml 的快速上手写法,本篇则把 0.10.7 的每一个配置项讲透——默认值、取值格式、生效时机、踩坑点,并附上可直接抄写的生产模板。

实测环境(与专栏 Compose 部署同构):

  • PushBits:ghcr.io/pushbits/server:0.10.7(镜像 digest 实查 2026-10-26)
  • Matrix homeserver:matrixdotorg/synapse:latest(自建,server name pushbits.local)
  • 网络:自建 bridge 网络 pushbits-0-10-7-net(10.89.62.0/24),两容器通过容器名互访
  • 端口:PushBits API 宿主机 8140 → 容器 8080;Synapse Client API 宿主机 127.0.0.1:8151 → 容器 8008
  • 演示账号:PushBits 管理员 admin/q1w2e3r4,Matrix 发送账号 pushbits/q1w2e3r4(演示口令,生产必须更换)
  • 环境变量覆盖实验:临时容器挂宿主机 127.0.0.1:8141、127.0.0.1:8142(同属分配给本组件的 8128-8152 端口槽)

二、配置加载机制:文件、环境变量与优先级

PushBits 0.10.7 使用 Go 的 configor 库加载配置(v0.10.7 源码 internal/configuration/configuration.go 实查):配置文件固定为当前工作目录下的 config.yml,同时支持 PUSHBITS_ 前缀的环境变量。加载出错(文件非法、必填项缺失)一律 panic 直接退出,没有"带病运行"的中间态——这是排障时判断"配置有没有被读到"的基本依据。

2.1 配置文件查找规则(裸机与容器两种布局)

裸机部署:从进程工作目录读 config.yml,无命令行参数可以指定路径(--help/--version 均不被识别)。工作目录不对时的实测表现(安装篇已录):打印 Failed to find configuration config.yml 后因缺必填项 panic。

容器部署:官方镜像的构建历史里有一组关键软链(docker history 实查):

RUN |1 USER_ID=1000 /bin/sh -c set -ex && apk add --no-cache ca-certificates curl ... && mkdir -p /data && ln -s /data/pushbits.db /app/pushbits.db && ln -s /data/config.yml /app/config.yml

即镜像内 /app(WORKDIR)下的 config.yml 是指向 /data/config.yml 的软链(ls -la /app 实查可见 config.yml -> /data/config.yml)。由此得到容器布局的结论:

  • 配置文件放数据卷里:宿主机 ./data/config.yml → 容器 /data/config.yml → 经软链被 /app 工作目录读到——官方 README 注释 "the configuration file would be located at ./data/config.yml" 与实测一致;
  • 也可以直接把文件挂到 /app/config.yml(实测可用,会覆盖软链挂载点),但推荐统一走 /data;
  • /data 目录不存在 config.yml 时,软链悬空,configor 打印 Failed to find configuration config.yml 后继续用环境变量/默认值启动——纯环境变量驱动完全可行(本专栏 Compose 栈即此形态,实测日志:Failed to find configuration config.yml 与后续正常启动并存)。

⚠️ 注意:/data/config.yml 若存在但是空文件,启动即 panic(实测回显):

level=info msg="Starting PushBits (devel)"
panic: EOF

空文件会被 YAML 解析器判定为非法输入。从模板复制后务必确认内容非空;touch config.yml 占位的习惯在 PushBits 这里会直接翻车。

2.2 环境变量命名规则与优先级

命名规则(官方文档):环境变量 = PUSHBITS_ 前缀 + 配置键路径(段名.键名)大写下划线拼接。例如 http.port → PUSHBITS_HTTP_PORT、admin.matrixid → PUSHBITS_ADMIN_MATRIXID、repairbehavior.resetroomname → PUSHBITS_REPAIRBEHAVIOR_RESETROOMNAME。

优先级:环境变量 > config.yml。两条实测证据:

  1. 官方镜像把 ENV PUSHBITS_HTTP_PORT=8080 固化进了镜像(docker history 回显 ENV PUSHBITS_HTTP_PORT=8080)。实测把写有 port: 8082 的 config.yml 挂进容器后,进程仍监听 8080(容器内 /proc/net/tcp 实查只有 8080 在监听)——文件里的端口被镜像内置环境变量覆盖了。容器里改端口必须用 -e PUSHBITS_HTTP_PORT=xxxx 覆盖环境变量,改文件无效。
  2. 临时容器设置 -e PUSHBITS_HTTP_PORT=8082(同名覆盖镜像内置值)后,宿主机 127.0.0.1:8142 → 容器 8082 映射正常通(/health 200),证明环境变量间同名覆盖同样遵循"后声明/更具体者生效"的常规语义。

docker inspect 实查镜像内置环境(容器运行时全量 ENV 仅两项):

["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","PUSHBITS_HTTP_PORT=8080"]

💡 技术拓展:镜像还内置了 HEALTHCHECK(curl --fail http://localhost:$PUSHBITS_HTTP_PORT/health),并以内置环境变量拼出检查端口——这是"改端口必须连环境变量一起改"的第二个原因:只改监听不改 PUSHBITS_HTTP_PORT,Docker 健康检查会持续探错端口导致容器被判 unhealthy。

2.3 数组型参数的环境变量写法(实测踩坑)

标量参数(字符串/整数/布尔)直接赋值即可,但数组型参数(如 http.trustedproxies)的环境变量值必须写成 YAML 流式数组,裸字符串会 panic。实测对照:

错误写法(-e PUSHBITS_HTTP_TRUSTEDPROXIES=10.89.62.0/24):

panic: yaml: unmarshal errors:
	  line 1: cannot unmarshal !!str `10.89.6...` into []string

正确写法(-e PUSHBITS_HTTP_TRUSTEDPROXIES="[10.89.62.0/24]"):启动正常,容器健康检查 200。

规则:数组值整体加引号写成 "[元素1,元素2]"(YAML flow 语法);同理若未来有 map 型参数,也应写 "{k: v}" 形态。这个坑在 config.yml 文件里不存在(文件里本来就是标准 YAML 语法),只出现在环境变量覆盖场景。

三、全参数速查表

以下按 config.yml 段落列出 0.10.7 全部参数(与官方 config.example.yml 逐项核对,"必填"标注来自官方注释与实测)。环境变量列仅给出键尾,实际使用加 PUSHBITS_ 前缀。

3.1 根级

键类型默认值必填环境变量说明
debugboolfalse否DEBUG调试日志开关;开启后 gin 路由表与 SQL 全打日志,排障临时用

3.2 http 段

键类型默认值必填环境变量说明
http.listenaddressstring""否HTTP_LISTENADDRESS监听地址;留空监听全部网卡
http.portint8080否HTTP_PORTAPI 端口;容器内被镜像内置 env 固定为 8080,覆盖须用 env
http.trustedproxies[]string[]否HTTP_TRUSTEDPROXIES信任的反代网段/CIDR 列表,用于还原 X-Forwarded-For 客户端 IP;env 写法见 2.3
http.certfilestring""否HTTP_CERTFILETLS 证书路径;与 keyfile 必须同空或同填,否则启动 log.Fatal(源码 validateHTTPConfiguration 实查)
http.keyfilestring""否HTTP_KEYFILETLS 私钥路径;官方建议 TLS 由反代终结,两项留空

3.3 database 段

键类型默认值必填环境变量说明
database.dialectstringsqlite3否DATABASE_DIALECT支持 sqlite3/mysql/postgres
database.connectionstringpushbits.db否DATABASE_CONNECTIONsqlite3 为库文件路径;mysql/pg 为 DSN 连接串(见 4.2)

3.4 admin 段

键类型默认值必填环境变量说明
admin.namestringadmin否ADMIN_NAME首次启动自动创建的管理员用户名
admin.passwordstringadmin否ADMIN_PASSWORD管理员初始密码;仅在首建时生效,之后改配置不改已存在账号
admin.matrixidstring""是ADMIN_MATRIXID管理员的 Matrix ID(@用户:域名);缺失启动即 panic: MatrixID is required, but blank

3.5 matrix 段

键类型默认值必填环境变量说明
matrix.homeserverstringhttps://matrix.org否MATRIX_HOMESERVER用于发通知的 homeserver 地址;不可达时启动 fatal(见 4.4)
matrix.usernamestring""是MATRIX_USERNAME发送账号用户名(PushBits 用它登录并建房/发信)
matrix.passwordstring""是MATRIX_PASSWORD发送账号密码

3.6 security 段

键类型默认值必填环境变量说明
security.checkhibpboolfalse否SECURITY_CHECKHIBP创建/修改密码时对接 Have I Been Pwned 校验弱口令;开启需实例能出网访问 API

3.7 crypto 段

键类型默认值必填环境变量说明
crypto.argon2.memoryint131072否CRYPTO_ARGON2_MEMORYArgon2 内存,单位 KB(默认 128 MB)
crypto.argon2.iterationsint4否CRYPTO_ARGON2_ITERATIONS迭代轮数
crypto.argon2.parallelismint4否CRYPTO_ARGON2_PARALLELISM并行度
crypto.argon2.saltlengthint16否CRYPTO_ARGON2_SALTLENGTH盐长度(字节)
crypto.argon2.keylengthint32否CRYPTO_ARGON2_KEYLENGTH派生密钥长度(字节)

3.8 formatting 段

键类型默认值必填环境变量说明
formatting.coloredtitleboolfalse否FORMATTING_COLOREDTITLE按 priority 给投递到 Matrix 的消息标题着色(分档见 4.7)

3.9 alertmanager 段

键类型默认值必填环境变量说明
alertmanager.annotationtitlestringtitle否ALERTMANAGER_ANNOTATIONTITLE从 Alertmanager 告警 annotations 里取标题的键名(实测可自定义,见 4.8)
alertmanager.annotationmessagestringmessage否ALERTMANAGER_ANNOTATIONMESSAGE从 annotations 里取正文的键名

3.10 repairbehavior 段

键类型默认值必填环境变量说明
repairbehavior.resetroomnamebooltrue否REPAIRBEHAVIOR_RESETROOMNAME启动修复时把被改动的房间名重置回 PushBits 设定值
repairbehavior.resetroomtopicbooltrue否REPAIRBEHAVIOR_RESETROOMTOPIC同上,作用于房间话题(topic)

四、重点参数实测详解

4.1 http 段:端口、反代与 TLS

  • http.port:裸机改文件即生效;容器里受镜像内置 PUSHBITS_HTTP_PORT=8080 覆盖(2.2 实测)。改端口后注意三处联动:反代 upstream、防火墙放行、镜像 HEALTHCHECK 端口。
  • http.trustedproxies:把反代所在网段写进列表后,日志里的 clientIP 会显示真实客户端 IP 而非反代地址。本专栏实测日志中 clientIP=10.89.62.1 即 Docker 网关(未配置信任时容器网桥地址会顶替真实来源)。
  • http.certfile/http.keyfile:两者必须同空或同填,源码 validateHTTPConfiguration 校验"一空一填"直接 Fatal(v0.10.7 源码实查)。自签/正式证书都放容器可读路径;更常见的做法是保持留空,让 Nginx/Caddy 终结 TLS。

4.2 database 段:三方言与 connection 格式

  • sqlite3:connection 是库文件路径。容器里必须落在挂载卷内(如 /data/pushbits.db),且宿主机目录属主需匹配镜像运行用户 uid 1000(实测:宿主目录未放权属时启动报 level=fatal msg="unable to open database file: no such file or directory")。
  • mysql:connection 写 go-sql-driver DSN,如 user:pass@tcp(127.0.0.1:3306)/pushbits?charset=utf8mb4&parseTime=True。
  • postgres:connection 写 pgx/libpq 连接串,如 postgres://user:pass@host:5432/pushbits。
  • 官方镜像还把 /app/pushbits.db 软链到 /data/pushbits.db(docker history 与 ls -la /app 实查),即容器内默认库路径天然落在数据卷,不额外配置也能持久化;显式写 PUSHBITS_DATABASE_CONNECTION=/data/pushbits.db 更清晰。

4.3 admin 段:创建时机是首启动一次性动作

实测两次首启对比(安装篇与本篇 Compose 栈):

  • 首次启动(空库):日志出现 Populating database.,随后按 admin.* 三项建号;
  • 非空库再启动:日志变为 Priviledged user admin already exists.——config.yml 里的 admin 密码不再生效,改密走 PUT /user/{id} API 或 CLI(本专栏 CLI 篇)。

admin.matrixid 是唯一必填项:缺失时启动即 panic: MatrixID is required, but blank(实测回显,goroutine 栈指向 configuration.go)。这个 ID 决定"用户创建、应用 token 变动"等管理事件投递到哪个 Matrix 账号。

4.4 matrix 段:发送账号三要素

homeserver/username/password 三项决定 PushBits 以哪个 Matrix 账号发通知。homeserver 不可达时的实测表现(本专栏 Compose 栈修复期间实录——synapse 容器循环重启时):

level=info msg="Setting up dispatcher."
level=fatal msg="request error: Post \"http://pushbits-0.10.7-synapse:8008/_matrix/client/v3/login\": dial tcp: lookup pushbits-0.10.7-synapse on 127.0.0.11:53: no such host"

要点:dispatcher 初始化在 HTTP 服务之前,homeserver 连不上/账号密码错都会让容器退出并进入 restart 循环——Compose 里给 PushBits 配 depends_on 只保证启动顺序不保证就绪,homeserver 启动慢时依赖 restart 策略自然重试。发送账号需预先在 homeserver 侧注册好(自建 Synapse 用 register_new_matrix_user,本专栏 Compose 篇有实录)。

4.5 security.checkhibp

开启后,创建用户/改密时会将密码前缀送往 HIBP API 比对泄露库。实测保持默认关闭即可用;开启前确认实例能出网(curl -sI https://api.pwnedpasswords.com/range/AAAA 返回 200),内网隔离环境开了会卡注册流程。

4.6 crypto.argon2

密码哈希 KDF 参数,默认 128 MB 内存/4 轮/并行 4。两点实测观察:常驻内存约 130 MB 与 memory=131072 直接相关(安装篇已录);小内存机器(1 GB 档)若感觉吃紧,可把 memory 降到 65536(64 MB),安全性略降但可接受。无特殊合规要求不建议动其他三项。

4.7 formatting.coloredtitle

开启后投递到 Matrix 的消息标题按 priority 分档着色(官方注释实查):<0 灰色、0-3 默认、4-10 黄色、10-20 橙色、>20 红色。实测注意:API 响应里的 title 始终是纯文本(对照实验:开启 coloredtitle 的临时容器,POST /alert 响应 title 无任何 HTML 标记),着色只发生在投递到 Matrix 房间的 HTML 消息体内。适合与告警类应用的 priority 4-10+ 档位配合使用。

4.8 alertmanager 段:注解键自定义实测

/alert 端点接收 Alertmanager webhook 报文,从每条 alert 的 annotations 里按 annotationtitle/annotationmessage 配置的键名取标题/正文。两组实测(自定义键 summary/description):

环境变量:

PUSHBITS_ALERTMANAGER_ANNOTATIONTITLE=summary
PUSHBITS_ALERTMANAGER_ANNOTATIONMESSAGE=description

发送(annotations 同时带默认键 title/message 与自定义键,验证只有配置键生效):

curl -s -X POST "http://127.0.0.1:8141/alert?token=$PB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"alerts":[{"status":"firing","labels":{"alertname":"CustomKeys"},"annotations":{"summary":"自定义 summary 键标题","description":"自定义 description 键正文","title":"这个不应出现","message":"这个也不应出现"}}]}'

实测回显(标题/正文确实取自 summary/description,且带状态前缀):

[{"id":"$_QqeT9PV6Z6iippJH-vLAFtarw9i8i4lGmXCRHIlUgU","appid":1,"message":"STATUS: firing\n\n自定义 description 键正文\n\nalertname: CustomKeys","title":"[FIR] 自定义 summary 键标题","priority":0,"date":"2026-10-26T13:40:15Z"}]

再发一条 status: "resolved" 的对照,标题前缀变为 [RES]:

{"title":"[RES] 已恢复告警","message":"STATUS: resolved\n\n指标回到阈值内\n\nalertname: CustomKeys", ...}

结论三条:通知标题 = [FIR]/[RES] 前缀 + 配置键取到的 annotation;正文自动组装 STATUS 行 + 配置键正文 + labels 明细;接入 Grafana Alertmanager 时把 webhook url 指到 http://pushbits:8080/alert?token=<应用token> 即可,注解键名按你们的告警规范用这两个配置项对齐。

4.9 repairbehavior 段:修复时机与孤儿房间

启动日志里的 Repairing application channels. 就是该段配置的作用现场。实测一个真实场景:应用 amtest 的 Matrix 房间在 homeserver 侧已成为孤儿(数据库里记着房间 ID 但会话已不可用),下次启动时日志出现:

level=info msg="Found orphan channel for application amtest (ID 1)"

随后 PushBits 重建房间并重新发送邀请。resetroomname/resetroomtopic 决定重建/修复时是否把用户手动改过的房间名与话题抹回 PushBits 默认值——希望保留人工定制就都设 false(环境变量写法:PUSHBITS_REPAIRBEHAVIOR_RESETROOMNAME=false)。

五、生产配置模板

文件形态(容器放 /data/config.yml,裸机放工作目录 config.yml;演示口令务必替换):

debug: false

http:
    listenaddress: ""              # 留空监听全部网卡
    port: 8080                     # 容器内改端口须同步覆盖 PUSHBITS_HTTP_PORT
    trustedproxies: []             # 反代网段,如 ["10.0.0.0/8"]
    certfile: ""                   # TLS 交给反代则留空
    keyfile: ""

database:
    dialect: "sqlite3"             # 或 mysql / postgres
    connection: "/data/pushbits.db"

admin:
    name: "admin"
    password: "q1w2e3r4"           # 仅首次建号生效
    matrixid: "@admin:pushbits.local"   # 必填;域名与 homeserver server name 一致

matrix:
    homeserver: "http://pushbits-0.10.7-synapse:8008"  # 自建 Synapse 容器名;公网用 https://matrix.org
    username: "pushbits"           # 预先注册好的发送账号
    password: "q1w2e3r4"

security:
    checkhibp: false               # 内网环境保持 false

crypto:
    argon2:
        memory: 131072
        iterations: 4
        parallelism: 4
        saltlength: 16
        keylength: 32

formatting:
    coloredtitle: true             # 按优先级着色,告警场景建议开

alertmanager:
    annotationtitle: title         # 按告警规范可改 summary 等
    annotationmessage: message

repairbehavior:
    resetroomname: true
    resetroomtopic: true

Compose 环境变量等价形态(本专栏 Compose 栈即此形态,免配置文件):

environment:
    PUSHBITS_DATABASE_DIALECT: "sqlite3"
    PUSHBITS_DATABASE_CONNECTION: "/data/pushbits.db"
    PUSHBITS_ADMIN_NAME: "admin"
    PUSHBITS_ADMIN_PASSWORD: "q1w2e3r4"
    PUSHBITS_ADMIN_MATRIXID: "@admin:pushbits.local"
    PUSHBITS_MATRIX_HOMESERVER: "http://pushbits-0.10.7-synapse:8008"
    PUSHBITS_MATRIX_USERNAME: "pushbits"
    PUSHBITS_MATRIX_PASSWORD: "q1w2e3r4"

两种形态取舍:文件形态便于版本化与一次改多项;env 形态便于 Compose/编排注入与密钥管理。混用时记住优先级——env 赢文件,排障时先 docker inspect <容器> --format '{{json .Config.Env}}' 看有没有内置/编排注入的同名变量。

六、常见问题(FAQ)

Q1:启动 panic: EOF? /data/config.yml 存在但是空文件(2.1 实测)。写入有效 YAML 内容或删除该文件改用纯环境变量驱动。

Q2:容器里改了 config.yml 的端口却不生效? 镜像内置 ENV PUSHBITS_HTTP_PORT=8080 覆盖了文件值(2.2 实测)。用 -e PUSHBITS_HTTP_PORT=<新端口> 覆盖环境变量,并同时改 Compose 的端口映射。

Q3:panic: yaml: unmarshal errors: cannot unmarshal !!str ... into []string? 数组型参数的环境变量值没用 YAML 流式写法。PUSHBITS_HTTP_TRUSTEDPROXIES="[10.89.62.0/24]"(2.3 实测)。

Q4:level=fatal msg="unable to open database file"? 两可能:database.connection 指向的目录不存在/不可写(容器内确认目录属主 uid 1000 可写:宿主机 chown -R 1000:1000 ./data);或 mysql/postgres 的 DSN 写错连不上。

Q5:启动 panic: MatrixID is required, but blank? admin.matrixid 未填,或环境变量写错键名导致没读到。完整格式 @用户名:homeserver域名,域名须与 homeserver 的 server name 一致。

Q6:改了 matrix.password 后启动 fatal M_LIMIT_EXCEEDED 或 M_FORBIDDEN? 发送账号在 homeserver 侧的密码与配置不一致,或频繁重启触发登录限流(安装篇 FAQ Q3 同源)。先在 homeserver 侧核对账号可手动登录,再等限流窗口过后重启 PushBits。

Q7:checkhibp 开了之后创建用户很慢或失败? 实例访问不了 HIBP API(出网受限)。关掉 security.checkhibp,或打通到 api.pwnedpasswords.com 的出网。

七、参考链接