运维自托管的 Chorus
本指南介绍部署完成后如何运维自托管的 Chorus:让第一个人登录进来、配置认证、安全升级,以及通过 HTTPS 提供服务时需要关注的 Cookie 与反向代理设置。关于如何把部署搭建起来,请参阅生产环境部署或使用 Docker 部署。
引导首次访问
Section titled “引导首次访问”全新部署可以使用托管本地账号,无需身份提供商。先配置下文的超级管理员凭据,再创建本地账号工作区并邀请首位工作区管理员。这与可选的 Default Auth 演示或引导入口不同。若要启用旧的引导入口,需同时设置:
DEFAULT_USER='admin@example.com' \DEFAULT_PASSWORD='choose-a-strong-password'两个变量都设置后,指定邮箱可以使用 Default Auth。首次成功登录时,Chorus 会按需创建用户和工作区,但不会创建托管本地账号或授予本地工作区管理员角色。登录先输入邮箱或用户名;匹配多个角色或工作区时,应选择所需入口。
关闭内置登录
Section titled “关闭内置登录”验证托管本地账号或 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 调用。本机部署指南中的隧道示例已包含对此文件的按需加载。
配置部署侧的认证
Section titled “配置部署侧的认证”Default Auth 和超级管理员凭据来自部署环境。托管本地账号和 OIDC 按工作区配置并保存在数据库中,不存在新的本地认证环境变量开关。
超级管理员引导
Section titled “超级管理员引导”/admin 超级管理员面板通过环境变量引导,而不是依赖数据库中的账号:
| 环境变量 | 说明 |
|---|---|
SUPER_ADMIN_EMAIL | 可访问 /admin 面板的超级管理员账号邮箱。 |
SUPER_ADMIN_PASSWORD_HASH | 超级管理员密码的 bcrypt 哈希值(绝不是明文)。 |
生成哈希并作为 SUPER_ADMIN_PASSWORD_HASH 传入:
node -e "console.log(require('bcryptjs').hashSync('your-password', 10))"托管本地账号工作区
Section titled “托管本地账号工作区”以超级管理员身份创建本地账号工作区,并邀请首位工作区管理员。通过私密渠道分享一次性链接;Chorus 不会发送邀请或重置密码邮件。接收者设置密码后,仍需单独登录。邀请和重置链接有效期为 24 小时,重新生成会使旧链接失效。后续用户和密码重置由处于启用状态的本地工作区管理员管理。此角色不是部署超级管理员,也不是由 DEFAULT_USER 授予的。
同一工作区的本地账号与 OIDC 互斥。创建时选择合适类型,不能通过编辑认证模式转换已有工作区。备份数据库和持久化的 NEXTAUTH_SECRET:本地密码以 bcrypt 哈希存储在数据库中(工作因子 12),本地会话则由此密钥签名。密码至少 8 个字符,最多 72 个 UTF-8 字节。共享访问时使用 HTTPS 和 COOKIE_SECURE=true。账号操作参见认证配置。
上文历史命名的 oidc-only.yml 只关闭 Default Auth,同样适用于托管本地账号工作区,并不会启用 OIDC。
单点登录(OIDC)
Section titled “单点登录(OIDC)”单点登录不通过环境变量配置。超级管理员在 /admin 面板中按工作区分别配置 OIDC,相关设置存储在数据库中。每个工作区都有各自的颁发者(issuer)URL 和客户端 ID,两者都填写后该工作区即启用单点登录。Chorus 使用 PKCE,不需要客户端密钥(client secret)。因此,部署层面的引导只负责让超级管理员登录进来,随后由超级管理员在管理面板中为各工作区配置单点登录,部署层无需另行准备任何密钥。
运行迁移与安全升级
Section titled “运行迁移与安全升级”Chorus 在启动时会自动应用待执行的数据库迁移(prisma migrate deploy)。你无需手动运行迁移:启动新版本时,Chorus 会先应用所有未完成的迁移,然后 Web 应用才开始提供服务。
升级步骤:
- 先备份数据库。 对于外部 PostgreSQL,请先做一次备份;对于内嵌或基于卷的数据库,请备份数据卷。
- 拉取新版本,npm 包使用
npm update -g @chorus-aidlc/chorus,Docker 部署则拉取新的容器镜像。 - 重启 Chorus。迁移会在启动时自动应用,随后应用开始运行。
对于包装脚本能加载全部必要覆盖文件的本地模式实例,运行 bash ./default_deploy_local.sh(pull 模式先更新 CHORUS_IMAGE)。若使用隧道模式、oidc-only.yml 或其他自定义覆盖文件,请先准备目标应用镜像,再使用完整的 Compose 调用。不要通过重跑安装器升级。PostgreSQL 大版本升级仍需单独进行离线迁移。参见在本机自托管。
0.19.1 的升级顺序
Section titled “0.19.1 的升级顺序”0.19.1 包含的迁移只添加一个可为空的列,现有数据不受影响。请先升级 Chorus 服务端,再升级运行智能体后台服务的 chorus CLI。旧版后台服务仍可与新服务端配合工作,并以它们已能理解的格式接收想法创建和调研请求。如需紧急回滚新的请求格式,请设置 CHORUS_DEDICATED_OPERATION_WRITES=false 并重启服务端:新请求会改用旧格式,已排队的请求仍会正常投递。如有需要,请单独回滚 CLI。只要仍有由新版服务端创建的请求处于待处理或运行中,就不要把服务端回滚到早于 0.19.1 的版本,也不要删除新增的列。
升级到 0.18.1 时的会话密钥
Section titled “升级到 0.18.1 时的会话密钥”请将签名密钥与数据库一并备份,并保持其不变。若要保留自动生成的密钥,即使使用外部 PostgreSQL,Docker
仍需持久的 /app/data 卷。npm 启动器默认使用 ~/.chorus-data/.secret。若此前使用公开占位值,更换密钥后
内置邮箱/密码登录的用户和超级管理员需要重新登录。你显式设置的安全密钥会原样保留。CDK 重新部署时需传入
同一个 nextAuthSecret,省略它会在每次 synth 时生成新值。API 密钥和 OIDC 令牌不受此轮换影响。参见 Docker 升级说明。
Cookie 与反向代理
Section titled “Cookie 与反向代理”当 Chorus 运行在终止 TLS 的代理或反向代理之后时,有两个设置需要关注:
| 环境变量 | 设为 | 适用场景 |
|---|---|---|
COOKIE_SECURE | true | 站点通过 HTTPS 提供服务(包括在终止 TLS 的代理之后)。安全 Cookie 只在加密连接上发送。 |
COOKIE_SECURE | false | 仅用于受信任的内部纯 HTTP 网络。此时 Cookie 会在未加密的 HTTP 上发送,切勿在公网上使用。 |
NEXTAUTH_URL | 对外的基础网址 | Chorus 运行在反向代理之后。将其设为对外可见的地址(例如 https://chorus.example.com),以保证重定向和链接正确解析。 |
共享认证限流
Section titled “共享认证限流”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 后应分别检查认证计数器和实时更新,再确认故障已恢复。