运行守护进程
主页的 CLI 涵盖了一次性和监听式同步。对于无人值守、按计划或由外部事件驱动的场景,请将 oikb 作为长期运行的守护进程运行。它读取您的 .oikb.yaml 文件,按各自的计划同步每个数据源,并暴露一个小型 HTTP API 用于健康检查、指标、历史记录和按需触发。
oikb daemon| 参数 | 默认值 | 用途 |
|---|---|---|
--port | 8080 | HTTP API 和健康检查的端口。 |
--config | ./.oikb.yaml | 配置文件的路径。 |
--log-format | text | text 或 json。也可由 LOG_FORMAT 设置。 |
--no-server | 关闭 | 仅运行调度器,不启动 HTTP 服务器(无 API、无 Webhook、无指标)。 |
启动时,它会打印已配置的数据源、身份验证是否启用以及端点 URL。
.oikb.yaml 配置文件
命令行上的单个数据源不需要配置文件。对于多个数据源、计划任务、Webhook 或守护进程,您需要在 .oikb.yaml 中描述所有内容。可使用 oikb init 交互式生成,或手动编写:
defaults: # 可选,应用于下方所有条目
interval: 1h
concurrency: 4
filter:
max-size: 50mb
sources:
- name: wiki # 用于 CLI/API 引用的友好别名
source: github:owner/repo
kb-id: 8f3a2b1c-...
webhook: true # 同时在推送时同步(参见 Webhook)
- name: handbook
source: confluence:ENG
kb-id: 4e7d9a0f-...
interval: "0 6 * * 1-5" # 覆盖默认 interval
notify:
url: https://hooks.slack.com/services/T.../B.../xxx
on: error每个条目的键: name、source、kb-id(其中 source 和 kb-id 是必需项)、interval、concurrency、branch、path、filter(include / exclude / max-size)、notify、webhook 以及各提供商的 Webhook 密钥(github_secret、gitlab_secret、slack_signing_secret)。您也可以在每个条目中设置 url 和 token,将不同的数据源指向不同的服务器。
Defaults 与每个条目进行深度合并,因此嵌套块(如 filter 和 notify)会组合而不是替换;条目上设置的任何键都会覆盖默认值。
环境变量插值: 每个字符串值都支持 ${VAR} 和 ${VAR:-default}。这使得机密信息不会出现在文件中,从而可以提交:
sources:
- name: docs
source: github:${GITHUB_ORG}/docs
kb-id: ${KB_DOCS_ID}
token: ${OPEN_WEBUI_API_KEY}
notify:
url: ${SLACK_WEBHOOK:-https://hooks.slack.com/fallback}顶层键是 sources:。旧的名称 sync: 仍然有效以保持向后兼容。
文件存在后,oikb sync(不提供数据源参数)会运行所有条目一次,而 oikb sync --name wiki 仅运行一个。
调度
每个条目的 interval 可以是简单持续时间或 Cron 表达式。oikb 通过计算字段数自动检测,无需指定标志:
interval: 30m # 简单:每 30 分钟
interval: 1h # 每小时
interval: "0 6 * * 1-5" # Cron:工作日 06:00
interval: "0 */6 * * *" # Cron:每 6 小时简单持续时间接受 s、m、h、d。同一文件中不同条目可以混用两种风格。
HTTP API
| 端 点 | 鉴权 | 描述 |
|---|---|---|
GET / | 公开 | 状态仪表板(一个轮询 /health 的小型页面)。 |
GET /health | 公开 | 每个数据源的同步状态:上次运行、持续时间、文件数、错误。 |
GET /health/ready | 公开 | Docker/Kubernetes 的存活探针。 |
GET /metrics | 公开 | Prometheus 指标。 |
GET /history | 🔒 | 同步历史,可按 kb_id 和 errors_only 过滤。 |
POST /sync/{name-or-kb-id} | 🔒 | 立即触发一次同步。添加 ?dry_run=true 仅预览。 |
POST /webhooks/github · /gitlab · /slack · /confluence | 签名 | 推送时实时同步(参见 Webhook)。 |
触发的同步在后台运行并立即返回;轮询 /health 查看进度。dry_run=true 触发的同步会同步执行并返回新增/修改/删除的计数。
身份验证
设置 OIKB_API_KEY 来保护守护进程。健康检查、就绪探针、指标和仪表板端点保持公开(以便探针和抓取器继续工作);/history 和 /sync 则需要 bearer token:
export OIKB_API_KEY=your-secret-key
oikb daemoncurl -X POST http://localhost:8080/sync/wiki \
-H "Authorization: Bearer your-secret-key"对于 Docker/Kubernetes 密钥,请设置 OIKB_API_KEY_FILE 指向文件路径,而不是将密钥放在环境变量中。(同时设置两者是错误的。)
Webhook
为某个条目开启 webhook: true,守护进程会在数据源变化的瞬间同步它,而不是等待下一个间隔。推送负载通过仓库或空间匹配到正确的条目,因此一个守护进程可以为多个数据源提供服务。
sources:
- name: docs
source: github:owner/repo
kb-id: abc123
webhook: true
github_secret: ${GITHUB_WEBHOOK_SECRET} # 验证负载签名然后在源系统中添加指向守护进程的 Webhook:
- GitHub → 仓库 Settings → Webhooks →
http://your-daemon:8080/webhooks/github。设置了github_secret时,会验证X-Hub-Signature-256HMAC,任何未签名或签名错误的内容将以403拒绝。 - GitLab →
…/webhooks/gitlab,通过gitlab_secret对照X-Gitlab-Token头进行验证。 - Slack →
…/webhooks/slack,使用slack_signing_secret进行验证(Slack 的 v0 请求签名)。该端点也会响应 Slack 的 URL 验证挑战。 - Confluence →
…/webhooks/confluence,按 space key 匹配。
如果不设置密钥,将跳过签名验证,因此在此情况下只能在受信网络中暴露守护进程。
同步锁
每个知识库都有其自己的锁。如果在某个知识库的计划同步仍在运行时 Webhook 触发了同步,重复的同步将被跳过(并记录日志),而不是与第一次同步竞争。这是自动的,无需任何配置。
可观测性
Prometheus 指标
GET /metrics 输出计数器和持续时间直方图,全部按数据源打标签:
| 指标 | 类型 | 含义 |
|---|---|---|
oikb_sync_total | counter | 同步次数,按数据源和状态。 |
oikb_sync_duration_seconds | histogram | 同步持续时间。 |
oikb_files_uploaded_total | counter | 新增和修改的文件数。 |
oikb_files_deleted_total | counter | 删除的文件数。 |
oikb_sync_errors_total | counter | 失败的同步。 |
oikb_info | gauge | 构建版本。 |
scrape_configs:
- job_name: oikb
static_configs:
- targets: ["oikb:8080"]结构化 JSON 日志
对于日志聚合器(Datadog、Splunk、ELK、CloudWatch、Loki),可输出每行一个 JSON 对象:
oikb daemon --log-format json # 或 LOG_FORMAT=json失败通知
在条目中添加 notify,可在同步失败时(或始终)将 JSON 负载 POST 到任意 HTTP 端点。该负载包含 text 字段,因此 Slack 传入的 Webhook 可以直接渲染它:
notify:
url: https://hooks.slack.com/services/T.../B.../xxx
on: error # error(默认)| always相同的形式适用于 PagerDuty、Opsgenie 或您自己的接收器。除了 text 之外,它还携带结构化字段(source、status、error、duration_ms、文件数)。