部署 Node / Docker
Node 宿主把权威状态写入 SQLite,把 Context 对象写入本地文件,并在同一服务中提供 HTTP、Dashboard 与设备 WebSocket。它适合单机自托管、内网、已有容器平台和需要本地强一致状态的场景。
如果你只想第一次试用,先完成5 分钟本地启动。如果你希望免维护主机或在边缘运行,比较 Cloudflare 一键部署与源码部署。
reverse proxy / TLS │ HTTP + WebSocket ▼tool-bridge Node container │ └── /data ├── state.sqlite3 └── objects/Node/SQLite 的优点是认证、注册和搜索索引读写具有本地强一致语义。代价是状态属于这台主机和这块卷:多个无共享状态的副本不会自动组成一个集群,也不能靠负载均衡器合并各自的树。
本页以单实例容器为基线。需要多副本、自动故障转移或跨区恢复时,应先为 SQLite、对象数据和设备会话设计明确的一致性方案,而不是直接复制容器。
- Docker 或兼容的容器运行时;
- 可持久化并备份的本地卷;
- 生产环境的 TLS 终结与域名;
- 一项 Secret 注入机制;
- Node.js 22+,仅用于生成 trust roots;
- 已选定并固定一个镜像版本。
1. 生成并保存 trust roots
Section titled “1. 生成并保存 trust roots”export TB_ADMIN_SK="$(node -e "console.log('tbk_'+require('crypto').randomBytes(32).toString('base64url'))")"export TB_ENCRYPTION_KEY="$(node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))")"把 Admin SK 保存到密码管理器,把两项值写入部署平台的 Secret。不要把真实值放进 Compose 文件、镜像层、Git 或普通环境配置。
已有 /data 状态时,TB_BOOTSTRAP_ADMIN_SK 不会覆盖现有管理员身份。丢失 Admin SK 不是通过重启并换一个环境变量就能恢复的。
2. 创建持久卷并启动
Section titled “2. 创建持久卷并启动”将 <version> 替换为你已经评估的明确版本:
docker volume create tool-bridge-data
docker run -d --name tool-bridge \ --restart unless-stopped \ -p 127.0.0.1:8787:8787 \ -v tool-bridge-data:/data \ -e TB_BOOTSTRAP_ADMIN_SK="$TB_ADMIN_SK" \ -e TB_SECRET_ENCRYPTION_KEY="$TB_ENCRYPTION_KEY" \ ghcr.io/tokenrollai/tool-bridge:<version>只把容器端口发布到回环地址,由反向代理负责公网或局域网入口。不要在没有 TLS、防火墙和访问策略的情况下把 8787 直接暴露到公网。
主要环境变量
Section titled “主要环境变量”| 变量 | 作用 | 生产要求 |
|---|---|---|
TB_BOOTSTRAP_ADMIN_SK |
首次引导 Admin SK | 必须通过 Secret 注入;缺失时默认拒绝启动 |
TB_SECRET_ENCRYPTION_KEY |
SecretStore 主密钥 | 32 字节 base64url;通过 Secret 注入并备份 |
TB_DATA_DIR |
SQLite 与对象根目录 | 容器默认使用 /data;必须挂持久卷 |
TB_HOST / TB_PORT |
Node 监听地址和端口 | 通常保持容器内部默认,由端口映射控制暴露 |
TB_CANONICAL_ORIGIN |
唯一规范 origin,固定 OAuth redirect | 使用 OAuth 或多入口反代时应显式设置 HTTPS origin |
TB_REMOTE_ALLOWLIST |
Federation host 后缀白名单 | 空值拒绝所有 remote |
TB_MAX_HOPS |
Remote Via 跳数上限 | 保持有限值;不要用超大值绕过环保护 |
TB_UI_DIR |
自定义 Dashboard 静态目录 | 通常不需要,默认从 dashboard 包加载 |
环境变量可能随版本演进。部署前用对应版本的 server 包说明和发布说明核对,不把本表当作永远完整的配置清单。
TB_ALLOW_INSECURE_BOOTSTRAP=true 与 TB_ALLOW_INSECURE_HTTP=true 都是本地开发逃生口,不应进入共享或生产环境。
3. 配置 TLS 反向代理
Section titled “3. 配置 TLS 反向代理”反向代理必须:
- 把唯一的
https://tb.example.com转发到http://127.0.0.1:8787; - 保留
Authorizationheader; - 支持 WebSocket upgrade,供
tb connect和设备会话使用; - 传递正确的原始 host/proto 语义;
- 不把请求 body、SK、Authorization 或含敏感参数的 URL 写入普通访问日志;
- 限制 Dashboard 和管理入口的网络暴露范围,不能以网络限制替代 SK 授权。
使用 OAuth 时设置:
TB_CANONICAL_ORIGIN=https://tb.example.com上游 OAuth 应只登记这一规范 origin 的回调地址,避免内网地址、IP、HTTP 和正式域名同时参与回调。
4. 部署后验证
Section titled “4. 部署后验证”curl --fail https://tb.example.com/healthztb login --base-url https://tb.example.com --profile productiontb use productiontb whoamitb tree --depth 2tb help system/statustb call system/status --tool get还应签发一把临时受限 SK,验证:
- 授权路径可读、可调用;
- 未授权路径返回 404;
- Dashboard
/ui使用同一 SK 得到一致结果; - 如果需要设备连接,完成一次
tb connect、断线和重连; - 根
~describe只返回实际装配的全局 capability;未装配 Search 时允许返回 404。
完整矩阵见生产上线检查清单。
5. 备份与恢复
Section titled “5. 备份与恢复”备份必须同时覆盖 SQLite 和 objects/。最简单的单实例策略是在停止写入后,对整个 /data 做一致快照。
停止容器后导出命名卷:
docker stop tool-bridgedocker run --rm \ -v tool-bridge-data:/data:ro \ -v "$PWD":/backup \ alpine \ tar czf /backup/tool-bridge-data.tgz -C /data .docker start tool-bridge备份包含 SK hash、SecretStore 密文与对象数据,但仍需要单独安全保管 TB_SECRET_ENCRYPTION_KEY 和 Admin SK。只有数据备份而没有加密根,不能完整恢复上游凭证。
恢复流程应在隔离环境定期演练:创建新卷、解压备份、使用同一加密密钥启动、验证 Admin/受限 SK、节点、Context 对象与一次真实调用。
6. 升级和回滚
Section titled “6. 升级和回滚”- 阅读目标版本发布说明,确认 pre-launch 行为变化;
- 记录当前镜像 digest/版本,停止写入并备份
/data; - 拉取目标版本;
- 用相同卷和 Secret 重建容器;
- 依次验证
/healthz、Admin~help、受限 SK、真实 Provider、Dashboard 和设备通道; - 失败时停止新容器,恢复备份并使用原版本镜像。
不要只看容器 health 就宣布升级完成。数据面、权限和真实 Provider 才是可用性证据。
容器循环重启
Section titled “容器循环重启”查看 docker logs tool-bridge。常见原因是缺 trust root、加密密钥格式错误、/data 无写权限或 SQLite 无法打开。
Dashboard 可打开但 API 404
Section titled “Dashboard 可打开但 API 404”检查反向代理是否把所有路径错误地回退到前端 index.html。SPA fallback 应只服务 /ui,不能吞掉根 ~help、system/* 和数据面。
Device 无法保持在线
Section titled “Device 无法保持在线”确认反向代理支持 WebSocket upgrade,没有为长连接设置过短请求超时,并且设备使用稳定 ID 和最小权限 SK。
重启后节点或 Secret 消失
Section titled “重启后节点或 Secret 消失”通常是没有挂载预期卷、TB_DATA_DIR 指向另一路径,或创建了新卷。先停止写入,检查实际 mount,再决定恢复;不要反复 bootstrap 制造更多状态。
- 完成生产上线检查清单;
- 配置CLI profile和受限 SK;
- 接入真实 Provider 后,按故障排查与升级保留脱敏诊断流程。