跳到主要内容

运行守护进程

主页的 CLI 涵盖了一次性和监听式同步。对于无人值守、按计划或由外部事件驱动的场景,请将 oikb 作为长期运行的守护进程运行。它读取您的 .oikb.yaml 文件,按各自的计划同步每个数据源,并暴露一个小型 HTTP API 用于健康检查、指标、历史记录和按需触发。

oikb daemon
参数默认值用途
--port8080HTTP API 和健康检查的端口。
--config./.oikb.yaml配置文件的路径。
--log-formattexttextjson。也可由 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

每个条目的键: namesourcekb-id(其中 sourcekb-id 是必需项)、intervalconcurrencybranchpathfilterinclude / exclude / max-size)、notifywebhook 以及各提供商的 Webhook 密钥(github_secretgitlab_secretslack_signing_secret)。您也可以在每个条目中设置 urltoken,将不同的数据源指向不同的服务器。

Defaults 与每个条目进行深度合并,因此嵌套块(如 filternotify)会组合而不是替换;条目上设置的任何键都会覆盖默认值。

环境变量插值: 每个字符串值都支持 ${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 小时

简单持续时间接受 smhd。同一文件中不同条目可以混用两种风格。


HTTP API

端点鉴权描述
GET /公开状态仪表板(一个轮询 /health 的小型页面)。
GET /health公开每个数据源的同步状态:上次运行、持续时间、文件数、错误。
GET /health/ready公开Docker/Kubernetes 的存活探针。
GET /metrics公开Prometheus 指标。
GET /history🔒同步历史,可按 kb_iderrors_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 daemon
curl -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-256 HMAC,任何未签名或签名错误的内容将以 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_totalcounter同步次数,按数据源和状态。
oikb_sync_duration_secondshistogram同步持续时间。
oikb_files_uploaded_totalcounter新增和修改的文件数。
oikb_files_deleted_totalcounter删除的文件数。
oikb_sync_errors_totalcounter失败的同步。
oikb_infogauge构建版本。
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 之外,它还携带结构化字段(sourcestatuserrorduration_ms、文件数)。

同步历史

每次运行都记录在本地 SQLite 数据库中。可通过 API(GET /history)或 CLI 查询:

oikb history                    # 最近的运行,表格视图
oikb history --errors           # 仅失败
oikb history --json             # 机器可读
oikb history --clear --days 7   # 清除 7 天前的条目

让模型触发同步

守护进程同时也是一个 OpenAPI 工具服务器。将 Open WebUI 指向它,模型就可以在聊天过程中作为工具调用触发同步、检查状态和读取同步历史:

您: 手册知识库看起来过时了。重新同步一下,并告诉我有什么变化。

(模型调用 trigger_sync,轮询 get_sync_status,然后回答。)

助手: 已重新同步 handbook:更新了 4 个文件,删除了 1 个。现在是最新的。

它在 GET /openapi.json 提供规范,恰好暴露三个操作(仪表板、指标、健康检查和 Webhook 路由被隐藏,因此模型只能看到有用的部分):

工具映射到功能
trigger_syncPOST /sync/{identifier}按别名或知识库 ID 启动同步(可选择 dry-run)。
get_sync_statusGET /health报告每个数据源的当前状态和上次结果。
get_sync_historyGET /history返回最近的同步运行记录。

要连接它:

  1. 首先确保安全。 设置 OIKB_API_KEY,使 /sync/history 不会对任何可以访问守护进程的人开放。
  2. 将守护进程的 URL(例如 http://oikb:8080)添加为工具服务器:Admin Settings → External Tools 用于全实例连接,或 Settings → Tools 用于个人连接。提供相同的 OIKB_API_KEY 作为连接的 API 密钥。

这是标准的 OpenAPI 工具服务器连接,与 OpenAPI / MCP 工具服务器 页面描述的机制相同;只是 oikb 恰好是另一端的事物。


部署

Docker

docker run -d \
  -e OPEN_WEBUI_URL=http://open-webui:8080 \
  -e OPEN_WEBUI_API_KEY=sk-... \
  -e OIKB_API_KEY=your-daemon-key \
  -e LOG_FORMAT=json \
  -v ./.oikb.yaml:/app/.oikb.yaml:ro \
  -p 8080:8080 \
  ghcr.io/open-webui/oikb:latest daemon

Docker Compose

在与 Open WebUI 同一网络下运行,使其能通过服务名访问服务器:

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    ports:
      - "3000:8080"

  oikb:
    image: ghcr.io/open-webui/oikb:latest
    environment:
      - OPEN_WEBUI_URL=http://open-webui:8080
      - OPEN_WEBUI_API_KEY=${OPEN_WEBUI_API_KEY}
      - OIKB_API_KEY=${OIKB_API_KEY}
      - LOG_FORMAT=json
    volumes:
      - ./.oikb.yaml:/app/.oikb.yaml:ro
    command: daemon
    ports:
      - "8080:8080"
    depends_on:
      - open-webui
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/ready"]
      interval: 30s
      timeout: 5s

Kubernetes

从 ConfigMap 挂载配置,从 Secret 拉取密钥,并将探针连接到健康端点:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: oikb
spec:
  replicas: 1
  selector:
    matchLabels: { app: oikb }
  template:
    metadata:
      labels: { app: oikb }
    spec:
      containers:
        - name: oikb
          image: ghcr.io/open-webui/oikb:latest
          args: ["daemon"]
          ports:
            - containerPort: 8080
          env:
            - name: OPEN_WEBUI_URL
              value: http://open-webui:8080
            - name: OPEN_WEBUI_API_KEY
              valueFrom: { secretKeyRef: { name: oikb-secrets, key: open-webui-api-key } }
            - name: OIKB_API_KEY
              valueFrom: { secretKeyRef: { name: oikb-secrets, key: oikb-api-key } }
            - name: LOG_FORMAT
              value: json
          volumeMounts:
            - name: config
              mountPath: /app/.oikb.yaml
              subPath: .oikb.yaml
          livenessProbe:
            httpGet: { path: /health/ready, port: 8080 }
            initialDelaySeconds: 5
            periodSeconds: 30
          readinessProbe:
            httpGet: { path: /health, port: 8080 }
            initialDelaySeconds: 10
            periodSeconds: 60
      volumes:
        - name: config
          configMap: { name: oikb-config }
运行单一副本

调度器和每个知识库的锁位于单个进程中,因此守护进程应作为单个副本运行。水平扩展会让两个调度器同时同步同一知识库。对于更多数据源,请向单个守护进程添加条目,而非运行同一配置的多个副本。

GitHub Actions

对于推送式、构建时同步(而不是长期运行的守护进程),可以将镜像作为一次性步骤运行。参见主页上的在 CI 中进行一次同步


另请参阅

本内容仅供参考,不构成任何保证、担保或合同承诺。Open WebUI 按“现状”提供。请参阅您的许可协议 以了解适用条款。