域名、HTTPS 与 OAuth
官方应用镜像在同一进程中提供网页和 /api。这意味着正常部署下浏览器和 API 始终同源:反向代理只需把整个请求转给应用,不需要分别部署前端、配置前端 API 地址或为单域名设置 CORS。
三种访问方式
| 方式 | 适用场景 | 安全边界 |
|---|---|---|
| 服务器 IP + HTTP | 首次短期验收 | 仅用于受控网络,不应承载真实账号或 OAuth |
| 本机反向代理 | 一台服务器上运行 Caddy、Nginx 或 Traefik | 应用只监听回环地址,代理占用 80/443 并终止 TLS |
| 云负载均衡/CDN | 云平台已有 HTTPS 入口 | 负载均衡终止 TLS,后端仅向负载均衡或私网开放 |
无论哪种方式,都不要通过代理暴露 PostgreSQL、Redis、Qdrant 或 sandbox。它们只应留在 Docker 内部网络或私有网络中。若使用 Cloudflare(橙色云代理或 Tunnel),SSE 流式响应、上传体积限制与回源 TLS 的额外注意事项见 Cloudflare 代理。
同机反向代理
默认 Compose 把应用映射为 80:8787。如果 Caddy、Nginx 或 Traefik 也运行在同一主机,先修改所用 Compose 文件中的 app.ports,改为只监听本机:
ports:
- "127.0.0.1:8787:8787"
重新创建应用后,代理可以连接 127.0.0.1:8787。以 Caddy 为例,站点配置可保持很简单:
aivory.example.com {
reverse_proxy 127.0.0.1:8787
}
DNS 将域名解析到服务器,防火墙只放行 80 与 443,然后验证:
curl -fsS http://127.0.0.1:8787/api/health
curl -fsS https://aivory.example.com/api/health
第二条命令应在证书签发完成后返回 {"ok":true}。反向代理必须转发正常的 Host 头;主流代理默认会这样做。
CORS 与拆分前端
官方镜像中没有 PUBLIC_ORIGIN 这类必填配置。只要网页和 API 由同一个 app 访问,用户通过哪个合法域名进入,应用就使用哪个域名工作。
ALLOWED_ORIGINS 仅用于你刻意把前端放到另一个 origin、让浏览器跨域访问 API 的情形。它应填写精确的 scheme://host[:port] 列表,例如:
ALLOWED_ORIGINS=https://console.example.com,https://staging-console.example.com
不要用宽泛通配符来替代受控域名列表。正常单体部署不需要设置它。
OAuth 回调:单域名
在管理员后台创建 GitHub、Google、Apple、OAuth2 或 OIDC 身份源时,先让公开 HTTPS 域名可用。将后台显示的回调地址逐字复制到服务商控制台;协议、域名、端口和路径都必须一致。
对于单域名部署,通常不设置 OAUTH_CALLBACK_BASE_URL。应用会根据用户发起登录时的公开地址构造回调。身份源的 Client ID、Client Secret 和回调地址必须来自同一个服务商应用配置。
OAuth 回调:多个域名
部分服务商只允许一个回调地址。如果 Aivory 同时由多个域名访问,应选一个固定的 HTTPS 主域名作为 OAuth 回调域名,并在环境中设置:
OAUTH_CALLBACK_BASE_URL=https://aivory.example.com
OAUTH_RETURN_ORIGINS=https://aivory.example.com,https://team.example.com
OAUTH_CALLBACK_BASE_URL 不带尾随 /,它决定发给服务商的固定回调 origin。OAUTH_RETURN_ORIGINS 是允许登录完成后返回的精确 origin 列表,也是防止开放重定向的安全边界;不要放入通配符、不受控预览域名或带路径的 URL。每个身份源控制台应只注册 canonical 域名对应的回调地址。
修改以上变量后重启 app,并用每个允许的域名分别完成一次登录测试。
GitHub 显示 token_exchange_failed
账号已经可以绑定但登录时失败,或日志出现 context deadline exceeded、github exchange failed,通常表示应用服务器无法在时限内访问 GitHub 的 token endpoint,而不是用户 GitHub 身份已经损坏。按顺序检查:
- 服务器的 DNS、IPv4/IPv6 路由、出口防火墙和代理是否允许到
github.com:443的 HTTPS 请求。 - 服务商控制台中的回调地址是否与公开 HTTPS 域名完全一致。
OAUTH_CALLBACK_BASE_URL、Client ID 与 Client Secret 是否属于同一 GitHub OAuth App。- 服务器时间是否正确;严重的时间偏差会使 OAuth state、Cookie 或签名校验失败。
- 若必须走企业代理,在应用运行环境设置标准 HTTP(S) 代理,并确认它没有拦截 GitHub 的 token 请求。
不要把 OAuth Client Secret、一次性回调参数、会话令牌或完整 .env 发到 issue、聊天记录或浏览器控制台。