跳转到内容

运维自托管的 Chorus

本指南介绍部署完成后如何运维自托管的 Chorus:让第一个人登录进来、配置认证、安全升级,以及通过 HTTPS 提供服务时需要关注的 Cookie 与反向代理设置。关于如何把部署搭建起来,请参阅生产环境部署或使用 Docker 部署。

全新部署可以使用托管本地账号,无需身份提供商。先配置下文的超级管理员凭据,再创建本地账号工作区并邀请首位工作区管理员。这与可选的 Default Auth 演示或引导入口不同。若要启用旧的引导入口,需同时设置:

Terminal window
DEFAULT_USER='admin@example.com' \
DEFAULT_PASSWORD='choose-a-strong-password'

两个变量都设置后,指定邮箱可以使用 Default Auth。首次成功登录时,Chorus 会按需创建用户和工作区,但不会创建托管本地账号或授予本地工作区管理员角色。登录先输入邮箱或用户名;匹配多个角色或工作区时,应选择所需入口。

验证托管本地账号或 OIDC 访问以及超级管理员登录后,从应用进程环境中移除 DEFAULT_USER 和 DEFAULT_PASSWORD,再重建或重启应用。这只关闭 Default Auth,不关闭托管本地账号的密码登录,也不会因此撤销已签发的会话。

对于安装器管理的 Compose 栈,私有 env 文件中的这两个值必须保持非空,因为基础 Compose 文件在变量插值时需要它们。请在私有目录中保存以下容器环境覆盖文件 oidc-only.yml:

services:
app:
environment:
DEFAULT_USER: ""
DEFAULT_PASSWORD: ""

在完整的 dc 命令中、"$@" 之前加入 -f "$HOME/.config/chorus-self-host/$PROJECT/oidc-only.yml",然后运行 dc config --quiet 和 dc up -d --wait --force-recreate app。以后每次启动或升级都必须保留该覆盖文件。保存的本地包装脚本不会加载 oidc-only.yml,完成此步骤后不要直接使用未修改的包装脚本;应先准备目标应用镜像,再使用完整的 Compose 调用。本机部署指南中的隧道示例已包含对此文件的按需加载。

Default Auth 和超级管理员凭据来自部署环境。托管本地账号和 OIDC 按工作区配置并保存在数据库中,不存在新的本地认证环境变量开关。

/admin 超级管理员面板通过环境变量引导,而不是依赖数据库中的账号:

环境变量说明
SUPER_ADMIN_EMAIL可访问 /admin 面板的超级管理员账号邮箱。
SUPER_ADMIN_PASSWORD_HASH超级管理员密码的 bcrypt 哈希值(绝不是明文)。

生成哈希并作为 SUPER_ADMIN_PASSWORD_HASH 传入:

Terminal window
node -e "console.log(require('bcryptjs').hashSync('your-password', 10))"

以超级管理员身份创建本地账号工作区,并邀请首位工作区管理员。通过私密渠道分享一次性链接;Chorus 不会发送邀请或重置密码邮件。接收者设置密码后,仍需单独登录。邀请和重置链接有效期为 24 小时,重新生成会使旧链接失效。后续用户和密码重置由处于启用状态的本地工作区管理员管理。此角色不是部署超级管理员,也不是由 DEFAULT_USER 授予的。

同一工作区的本地账号与 OIDC 互斥。创建时选择合适类型,不能通过编辑认证模式转换已有工作区。备份数据库和持久化的 NEXTAUTH_SECRET:本地密码以 bcrypt 哈希存储在数据库中(工作因子 12),本地会话则由此密钥签名。密码至少 8 个字符,最多 72 个 UTF-8 字节。共享访问时使用 HTTPS 和 COOKIE_SECURE=true。账号操作参见认证配置。

上文历史命名的 oidc-only.yml 只关闭 Default Auth,同样适用于托管本地账号工作区,并不会启用 OIDC。

单点登录不通过环境变量配置。超级管理员在 /admin 面板中按工作区分别配置 OIDC,相关设置存储在数据库中。每个工作区都有各自的颁发者(issuer)URL 和客户端 ID,两者都填写后该工作区即启用单点登录。Chorus 使用 PKCE,不需要客户端密钥(client secret)。因此,部署层面的引导只负责让超级管理员登录进来,随后由超级管理员在管理面板中为各工作区配置单点登录,部署层无需另行准备任何密钥。

Chorus 在启动时会自动应用待执行的数据库迁移(prisma migrate deploy)。你无需手动运行迁移:启动新版本时,Chorus 会先应用所有未完成的迁移,然后 Web 应用才开始提供服务。

升级步骤:

  1. 先备份数据库。 对于外部 PostgreSQL,请先做一次备份;对于内嵌或基于卷的数据库,请备份数据卷。
  2. 拉取新版本,npm 包使用 npm update -g @chorus-aidlc/chorus,Docker 部署则拉取新的容器镜像。
  3. 重启 Chorus。迁移会在启动时自动应用,随后应用开始运行。

对于包装脚本能加载全部必要覆盖文件的本地模式实例,运行 bash ./default_deploy_local.sh(pull 模式先更新 CHORUS_IMAGE)。若使用隧道模式、oidc-only.yml 或其他自定义覆盖文件,请先准备目标应用镜像,再使用完整的 Compose 调用。不要通过重跑安装器升级。PostgreSQL 大版本升级仍需单独进行离线迁移。参见在本机自托管。

0.19.1 包含的迁移只添加一个可为空的列,现有数据不受影响。请先升级 Chorus 服务端,再升级运行智能体后台服务的 chorus CLI。旧版后台服务仍可与新服务端配合工作,并以它们已能理解的格式接收想法创建和调研请求。如需紧急回滚新的请求格式,请设置 CHORUS_DEDICATED_OPERATION_WRITES=false 并重启服务端:新请求会改用旧格式,已排队的请求仍会正常投递。如有需要,请单独回滚 CLI。只要仍有由新版服务端创建的请求处于待处理或运行中,就不要把服务端回滚到早于 0.19.1 的版本,也不要删除新增的列。

请将签名密钥与数据库一并备份,并保持其不变。若要保留自动生成的密钥,即使使用外部 PostgreSQL,Docker 仍需持久的 /app/data 卷。npm 启动器默认使用 ~/.chorus-data/.secret。若此前使用公开占位值,更换密钥后 内置邮箱/密码登录的用户和超级管理员需要重新登录。你显式设置的安全密钥会原样保留。CDK 重新部署时需传入 同一个 nextAuthSecret,省略它会在每次 synth 时生成新值。API 密钥和 OIDC 令牌不受此轮换影响。参见 Docker 升级说明。

当 Chorus 运行在终止 TLS 的代理或反向代理之后时,有两个设置需要关注:

环境变量设为适用场景
COOKIE_SECUREtrue站点通过 HTTPS 提供服务(包括在终止 TLS 的代理之后)。安全 Cookie 只在加密连接上发送。
COOKIE_SECUREfalse仅用于受信任的内部纯 HTTP 网络。此时 Cookie 会在未加密的 HTTP 上发送,切勿在公网上使用。
NEXTAUTH_URL对外的基础网址Chorus 运行在反向代理之后。将其设为对外可见的地址(例如 https://chorus.example.com),以保证重定向和链接正确解析。

Redis 有两种独立用途:Pub/Sub 传播 SSE 实时更新,另一个请求连接存储共享认证计数器。所有副本必须使用同一个 Redis 才能保持限流一致;SSE 正常并不代表认证计数器也正常。

  • 身份查找每 60 秒允许 30 次,本地密码登录和邀请/重置链接确认分别每 60 秒允许 10 次。这些值固定,不能通过环境变量调整。
  • 没有可信客户端地址时,按规范化的标识符、本地登录的工作区与标识符组合,或确认时的凭据令牌限流,并非所有用户共用一个桶。有可信地址时,每种操作同时应用“地址加身份”和独立的地址计数器,避免通过轮换标识符绕过地址限制。
  • 超限返回 HTTP 429、RATE_LIMITED 和以秒计的 Retry-After(向上取整,至少 1 秒)。这不覆盖所有登录或 API 端点,仍需在边缘层保护完整的认证入口。

配置与默认值:

  • 非空的 REDIS_URL 优先。否则,REDIS_HOST 启用 TLS(rediss)连接,REDIS_PORT 默认 6379,REDIS_USERNAME 默认 default,REDIS_PASSWORD 可选。提供密码时才使用用户名。非 TLS Redis 应显式使用 redis:// URL。URL 和 host 均未设置时才是不配置 Redis。
  • AUTH_TRUST_PROXY 仅在值恰好为 true 时启用;AUTH_TRUST_PROXY_HOPS 默认 1,必须是 1 到 16 的整数。从 X-Forwarded-For 右侧按跳数取地址;缺失、长度不足或无效的链只禁用地址限流,身份限流仍生效。只有在代理强制追加或覆盖转发链、且无法直接或中途绕过时才启用信任。HTTPS 本身不能建立这种信任。
  • 内置 CDK 的 ALB 模式设为信任 true、跳数 1;CloudFront 模式设为信任 false、跳数 2,因为 VPC 流量仍可绕过 CloudFront 到达私有源站。关闭该旁路前不要启用两跳信任。

未配置 Redis 时使用进程内计数器并记录警告。已配置的 Redis 正在连接、不可用或拒绝命令(包括 READONLY/OOM)时,限流器使用每进程独立的内存备用计数器,不再共享。Redis 命令超时为 500 ms;存在待处理命令却没有响应的 socket 在 2,000 ms 后重建;重连后不重放未完成的命令。500 ms 是每条命令的限制,不是整个请求的响应时间保证。

监控 auth-throttle 日志中的降级和恢复信息。备用限流警告每 60 秒最多一次,首次连接有 5 秒宽限期。内存计数器共用 10,000 个键的容量,按最近最少使用淘汰,因此只提供尽力保护;进程重启即清空,恢复后不会合并回 Redis。正常备用处理之外的限流后端意外错误会记录日志,并对该次检查放行(fail-open)。Redis 故障并不会有意阻止所有登录。

账号校验仍然独立,并在失败时拒绝访问(fail-closed):禁用或删除的本地用户、不兼容的工作区模式、过期的会话版本都不能授权本地会话;读取账号状态失败也不会授予访问权限。备用限流同样不能恢复跨实例 SSE,本地事件可能继续,但跨实例更新可能中断。恢复 Redis 后应分别检查认证计数器和实时更新,再确认故障已恢复。