部署与高匿名

先选部署形态

你基本会落在下面三种形态之一:

  • 本机或单机容器 POC:先确认镜像、控制台和接口能跑起来
  • 自托管长期运行:自己终止 TLS,并使用内置管理员登录
  • 网关模式:把 Hikari 放在 Caddy / Nginx / Traefik 等反代后面,通过 ForwardAuth 注入管理员身份头

最小运行参数

无论你选哪种形态,下面这组参数是最核心的:

Flag / Env 说明
--bind / PROXY_BIND 服务监听地址
--port / PROXY_PORT 服务监听端口
--db-path / PROXY_DB_PATH SQLite 数据库路径
--static-dir / WEB_STATIC_DIR 前端静态资源目录
--upstream / TAVILY_UPSTREAM Tavily MCP 上游地址
TAVILY_USAGE_BASE Tavily HTTP / usage 上游基地址

然后你还需要再补一类“管理员访问策略”:

  • ForwardAuth:推荐给生产或零信任网关
  • 内置管理员登录:适合自托管单实例
  • DEV_OPEN_ADMIN=true:只适合本地/临时验证

最小 Compose 部署

仓库根目录自带的 docker-compose.yml 会直接启动 Hikari:

docker compose up -d
curl -i http://127.0.0.1:8787/health

这个 compose 文件已经帮你做了:

  • 监听 0.0.0.0:8787
  • 挂载 tavily-hikari-data volume
  • 把数据库持久化到 /srv/app/data/tavily_proxy.db
  • 使用镜像 ghcr.io/ivanli-cn/tavily-hikari:latest

但它不会帮你自动提供管理员入口,所以第一次上线前还要补一层:

  • 临时本地验证:自己在环境变量里加 DEV_OPEN_ADMIN=true
  • 自托管:启用内置管理员登录
  • 正式网关:换成 examples/forwardauth-caddy

ForwardAuth 网关示例

生产环境通常建议把 Tavily Hikari 部署在可信网关后面,由网关负责 TLS 终止与管理员身份头注入。

仓库现成样例在:

直接启动:

cd examples/forwardauth-caddy
docker compose up -d

这个示例会拉起:

  • Caddy 网关
  • auth-mock,负责模拟 ForwardAuth
  • upstream-mock,负责模拟 Tavily 上游
  • Tavily Hikari

默认行为:

  • GET /health 公开可访问
  • 其余路径都要先通过 Basic Auth
  • 认证成功后,Caddy 会把 Remote-EmailRemote-Name 转发给 Hikari
  • Hikari 会把 Remote-Email=admin@example.com 视为管理员

如果你想先验证网关链路,而不是马上连真实 Tavily 与真实 SSO,这个示例就是最短路径。

内置管理员登录自托管

如果你没有独立的 ForwardAuth 网关,可以直接开启内置管理员登录。

推荐做法:

export ADMIN_AUTH_BUILTIN_ENABLED=true
echo -n 'change-me' | cargo run --quiet --bin admin_password_hash
export ADMIN_AUTH_BUILTIN_PASSWORD_HASH='<phc-string>'
export ADMIN_AUTH_FORWARD_ENABLED=false

部署要点:

  • 优先使用 ADMIN_AUTH_BUILTIN_PASSWORD_HASH,不要长期保留明文密码
  • 确保 TLS 终止可信,这样 session cookie 才能稳定带 Secure
  • 把它视为自托管便利模式,而不是默认生产零信任方案

真实上线前的检查项

  • /health 返回 200
  • 至少注册 1 把上游 Tavily key
  • 管理员能进入 /admin 或调通 /api/keys
  • 至少成功跑通 1 次 /api/tavily/search/mcp
  • 数据库目录已经持久化,不会因为容器重启而丢失

持久化、备份与升级

需要长期保留的数据不只是一份主库:

  • core DB:默认容器路径 /srv/app/data/tavily_proxy.db
  • observability sidecar:默认容器路径 /srv/app/data/tavily_proxy-observability.db
  • 如果你还维护了 Caddy / 反代配置,也应该把这部分一起纳入备份

升级要点:

  • 容器镜像本身是无状态的,升级通常就是换 tag 后重启
  • 升级前不要只拷 tavily_proxy.db;离线验证或回滚准备应把 core DB 与 observability sidecar 一起作为完整数据库集处理
  • 如需生成只读快照,优先用仓库里的 scripts/export-live-db-snapshot-to-testbox.sh。它会对两份 SQLite 都执行 .backup、记录 SHA-256,并验证 PRAGMA integrity_check
  • 若线上容器已更新到新镜像,记得同步清理本次维护产生的临时快照目录、孤儿大文件与 dangling image,避免磁盘残留继续放大运维风险

SQLite 与 HA 维护窗口建议

如果你遇到 database is lockedquota_sync 长时间停在 runningha_outbox backlog 过大、或者 SQLite 文件体积明显失控,建议把恢复步骤固定成同一套剧本:

  1. 先更新到目标镜像,并做一次受控重启
  2. 验证 /health 返回 200
  3. 检查 scheduled_jobs 里没有新的长时间 quota_sync* running
  4. 检查日志里 database is locked 不再持续爆发
  5. request logs backlog 优先运行 request_logs_gc_once
  6. ha_outbox backlog 先修 trigger,再运行 ha_outbox_cleanup_oncescripts/ha-outbox-maintenance.sh
  7. 只有在 reclaimable_bytes >= 512MB,或者你明确进入维护窗口时,再运行 db_compaction_once
  8. 维护完成后清理临时快照目录、离线备份中间文件和 dangling image,避免把磁盘再次打满

容器镜像内置了这些 operator CLI:

request_logs_gc_once --json
ha_outbox_cleanup_once --json
ha_trigger_repair_once --json
db_compaction_once --json
db_compaction_once --json --force

如需对大 backlog 做离线演练,先在 101 导出完整只读快照,再上传到 shared testbox:

scripts/export-live-db-snapshot-to-testbox.sh

说明:

  • request_logs_gc_once 用于 bounded 地清理 request logs / body backlog
  • ha_trigger_repair_once 用于显式修复升级库中残留的旧 trg_ha_outbox_* trigger;如果真实问题是旧 trigger 还在持续写 ha_outbox,必须先跑它
  • ha_outbox_cleanup_once 用于 bounded 地清理历史 HA outbox backlog;它支持 --repair-triggers,并会在报告中区分 invalid legacy 删除量与正常 retention 删除量。线上 scheduler 里的 ha_outbox_gc 只负责轻量 freshness cleanup,不负责重型历史收缩
  • scripts/ha-outbox-maintenance.sh 是一层运维封装,顺序固定为“先 repair + cleanup,后按需 compaction”
  • db_compaction_once 用于 SQLite 文件压缩;默认会尊重 reclaimable space 阈值,不满足条件时返回 skipped=true
  • db_compaction_once --force 只建议在明确的维护窗口里使用
  • 离线验证输入必须是完整数据库集:tavily_proxy.db + tavily_proxy-observability.db,不能只拷主库

高匿名透传

Hikari 支持在转发上游时清洗或重写敏感请求头。

它会重点处理这些事:

  • 丢弃 ForwardedX-Forwarded-*ViaCF-* 等链路暴露头
  • 需要时改写 OriginReferer
  • 在数据库里记录 forwarded_headersdropped_headers,方便排障

设计背景与更细的匿名策略说明,见:

docs/high-anonymity-proxy.md

暴露面建议

典型暴露面包括:

  • 公开首页与用户控制台
  • /admin 管理端
  • /api/tavily/* 给 HTTP 客户端用
  • /mcp 给 MCP 流量用

发版形态

主运行时产物是容器镜像:

ghcr.io/ivanli-cn/tavily-hikari:<tag>

它内含前端静态资源。公开 docs-site 与 Storybook 则通过 GitHub Pages 单独发布。

如果你部署后卡在管理员入口、数据库持久化或上游 502,继续看 FAQ 与排障