配置说明
按类别说明环境变量、密钥轮换和可选服务的启用方式。
先复制实例提供的 .env.example,再把秘密写入受保护的 .env 或部署平台 Secret。下面只列配置名称和行为,不放真实值;示例中的占位符请替换后使用。
数据库和服务
| 变量 | 用途 |
|---|---|
DATABASE_URL | PostgreSQL 连接字符串。 |
DB_PASSWORD | Docker Compose 数据库密码。 |
PORT | 容器内部默认监听 3000;使用 docker-compose.direct.yml 时作为宿主机映射端口。.env.example 填写 43100,未设置时宿主机默认使用 9600。 |
BACKUP_DIR | 本地备份目录;未设置时使用应用默认目录。 |
BETTER_AUTH_URL | 生产环境实际公开 origin,必须使用 HTTPS。 |
BETTER_AUTH_SECRET | Better Auth 会话和加密用途的稳定密钥,至少 32 位随机值。 |
AUTH_OWNER_EMAIL | 首次启动时创建 owner 的邮箱。 |
PANEL_PASSWORD | 仅用于首次 bootstrap 的密码;首次成功登录并修改密码后删除。 |
BETTER_AUTH_URL 只填写 origin,不要带末尾 / 或 API 路径。更换 BETTER_AUTH_SECRET 会使已有认证会话失效。
Bot 和加密
| 变量 | 用途 |
|---|---|
BOT_TOKEN | 首次迁移或开发时使用的 Telegram Token;长期配置可保存到面板数据库。 |
ADMIN_CHAT_IDS | 首次迁移时写入的管理员 Telegram ID 数组。 |
ENCRYPTION_KEY | 加密 Bot Token、API Key 等敏感配置的稳定密钥。 |
MINI_APP_SESSION_SECRET | Mini App 独立会话签名密钥。 |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | 可选 Google OAuth;两个必须同时配置。 |
所有环境都必须显式设置非空 ENCRYPTION_KEY,包括本地开发;缺失时应用会在启动时拒绝运行。全新 Docker 实例可按部署指南使用 pnpm setup:env --email owner@example.com --url https://bot.example.com 生成配置,并替换示例邮箱与域名。本地开发复制 .env.example 后,可用 openssl rand -hex 32 生成独立随机密钥,安全写入配置后再启动。应用按原值派生加密密钥,两端空格也属于密钥的一部分。
已有数据的实例必须保留原密钥,不要重新运行初始化工具来替换配置。若旧版本使用了内置默认值,先按备份与升级中的离线步骤恢复并显式保存旧值。升级工具只保留密钥,不执行轮换;更换它会导致旧密文无法解密。
Mini App secret 与 Better Auth secret、Bot Token 分开生成;轮换 Mini App secret 会让现有 Mini App 会话失效。
AI、媒体和清理
| 变量 | 用途 |
|---|---|
EMBEDDING_DIMENSIONS | embedding 维度,默认 3072;变更后需要迁移和重新索引。 |
PIXAI_MCP_URL | 旧部署兼容:PixAI MCP 完整地址。首次保存页面中的图片 MCP 平台地址后不再使用。 |
NSFW_API_URL | 图片内容安全服务地址,接口须支持 POST /classify 和 multipart image。未配置或检测失败时,Bot 保守遮罩照片。Docker 默认使用 http://nsfw-api:3000。 |
LOG_RETENTION_DAYS | 普通日志保留天数。 |
LOG_RETENTION_DAYS_ERROR | 错误日志保留天数。 |
LOG_CLEANUP_INTERVAL_HOURS | 日志清理间隔。 |
GENERATION_RETENTION_DAYS | 图片生成记录和文件的默认保留策略。 |
OPENAI_IMAGE_MCP_URL | 旧部署兼容:GPT 生图 MCP 完整地址。新配置请使用面板中的图片 MCP 平台地址。 |
GEMINI_IMAGE_MCP_URL | 旧部署兼容:Gemini 生图 MCP 完整地址。新配置请使用面板中的图片 MCP 平台地址。 |
Embedding 维度必须与数据库列一致。已经部署后直接修改它,可能导致迁移和索引不兼容;应先生成并审查迁移,再安排回填。
Embedding 响应会逐批检查数量和维度;带索引的结果按输入索引还原顺序,全部省略索引的兼容服务继续按返回顺序处理。缺项、重复或混合索引、错误维度等无效响应会按生成失败降级,不把不可靠的向量写入记忆或会话。
手动运行历史向量回填脚本时,每个 Bot 的记忆和对话消息分别按本轮开始时的 ID 上界扫描,每条记录最多尝试一次。每批供应商请求设置 5 分钟超时取消;超时按生成失败计入统计,并继续下一批。这个上限不包含数据库操作,也不限制整个脚本的总时长。供应商未返回向量的记录仍保留为空,可在故障排除后人工重跑;新插入的记录留待下一轮。等待结果期间内容已变更、向量已被其他任务填充或记录已删除时,本轮会跳过写入。仅补充记忆向量不会改变编辑版本或最近更新排序。终端分别显示尝试、实际保存、生成失败和并发跳过数量,扫描结束不代表所有向量均已补齐。回填会调用已配置的 Embedding 服务,应按实际供应商计费评估后执行。
NSFW 图片检测
NSFW_API_URL 填检测服务的基础地址,不带 /classify。所有生图供应商共用检测流程,正常评分按 porn + hentai + sexy 与阈值比较,默认阈值 0.5。Telegram 相册会先检测每张照片,任意一张需要遮罩时,整批照片加罩;全部低于阈值时直接显示。调用方明确要求的 spoiler 也会保留。
本地运行 Node.js
Docker 运行后,仅启动本地检测服务:
docker compose -p cos-bot-dev -f docker-compose.dev.yml up -d nsfw-api在根目录 .env 填写并重启本地服务:
NSFW_API_URL=http://localhost:43106如修改了 NSFW_API_PORT,地址端口也要同步修改。
Docker Compose 或 Dokploy
应用容器通过 Compose 服务名访问检测容器:
NSFW_API_URL=http://nsfw-api:3000Compose 默认使用此地址;如果从 .env.example 复制了本地开发配置,须覆盖其中的 localhost:43106。容器里的 localhost 指向应用容器本身,不能访问另一个检测容器。Dokploy 中修改应用环境变量后重新部署,Compose 中修改后重新创建应用容器使环境变量生效。
排查所有图片都被遮罩
先在应用实际运行的环境中检查该变量与检测服务连通性,不能只看开发机的 .env。未配置、请求超时、HTTP 错误或响应无有效评分都会加罩;这不代表图片被判定为 NSFW。
本地可以使用自己的测试图片检查分类接口:
curl --fail --max-time 15 -F 'image=@/path/to/test.jpg' http://localhost:43106/classify应返回包含 porn、sexy、hentai、neutral、drawing 五个数值的 JSON,每项在 0 到 1 之间。仅首页可访问不代表分类成功。日志中的 NSFW classification failed; applying spoiler 表示检测未成功,生成记录中的 failed / unavailable 与 checked 也应区分查看。
公共音频转录账户
ASR 账户在管理面板 设置 → 公共音频转录 保存,供所有 Bot 共用,不读取聊天模型 API Key,也不需要新增环境变量放供应商凭据。每家供应商一个账户,默认停用;密钥用现有 ENCRYPTION_KEY 加密。恢复备份时须保留同一加密密钥,否则账户凭据无法解密。
预置首选腾讯云常规录音识别 16k_zh,随后是阿里云百炼北京地域 paraformer-v2、Groq Whisper 和 OpenAI 兼容服务。腾讯云填 SecretId / SecretKey 和地域,其他服务填 API Key;未填凭据或单价未知的账户不会执行。Groq 零单价须管理员显式确认该密钥属于免费计划,应用不自动查询账号计划。
公共设置管理每分钟单价、单任务费用上限、账户每日和每月预算及月分钟数;Bot 插件仍独立控制启用、音频外传、Bot 限额和导出。价格和额度必须核对当前供应商控制台,免费余额未知时按全价预留。默认 CNY 单任务 / 每日 / 每月预算为 1 / 3 / 10,USD 为 0.2 / 0.6 / 2,分币种统计。
使用百炼或向腾讯云提交超过 5 MiB 的音频时,BETTER_AUTH_URL 必须是供应商可访问的公网 HTTPS origin。应用为已确认任务提供有时限的签名音频下载地址;不要把该地址作为公共文件链接分享。腾讯云较短音频直传与 Groq / OpenAI 兼容上传不依赖此地址。音频处理仍需按Docker 部署指南启动隔离转换服务。
旧版各 Bot 的 OpenAI ASR 配置不会自动复制到公共账户。升级前后核对所需供应商凭据,在公共设置保存后,再复核并保存提示清单变化的 Bilibili 插件。每次 ASR 都需原聊天里发起任务的管理员本人确认;所有者开启全局服务或 Bot 外传开关不能代替这次确认。流程和公开免费规则见插件管理。
GitHub 与编码 Worker
GitHub App 的五项变量需要全部配置或全部留空:GITHUB_APP_ID、GITHUB_APP_CLIENT_ID、GITHUB_APP_CLIENT_SECRET、GITHUB_APP_PRIVATE_KEY 和 GITHUB_APP_SLUG。私钥用单行加字面 \n 的 PEM 形式保存。
启用隔离 worker 时同时设置:
COMPOSE_PROFILES=coding
CODING_WORKER_SECRET=生成的独立随机值可选的 CODING_WORKER_URL、CODING_WORKER_SOCKET、CODING_JOB_DIR、CODING_WORKSPACES_DIR 和 CODING_GIT_DIR 描述内部连接和持久化目录。不要把 worker secret 当作模型或 GitHub 凭据。
轮换规则
轮换前先确认备份和回滚路径。认证 secret、Mini App secret、加密 key、Bot Token、GitHub 私钥、MCP/API Key 和邮箱应用密码的失效范围不同;每次只轮换一类,重启后检查健康接口、面板登录、Bot 连通和对应集成。
生图供应商与默认预设
以 owner 身份在任意 Bot 的 用量与生图治理 → 图片 MCP 平台 中填写一个平台域名,例如 mcp.example.com,保存后立即为所有 Bot 配置 PixAI、GPT Image 和 Gemini Image 的接口地址,无需新增环境变量或重启。设置持久化到现有数据库;更换平台会清除受影响连接的授权,清空后保存会关闭三个连接。
先在 MCP Platform 保存对应供应商的连接和 API key,再在 Hanori 的连接卡片中分别授权;三个供应商可以同时连接。GPT / Gemini 的预设可选,未填写时使用平台供应商连接的默认配置。完整步骤和旧部署兼容行为见 图片 MCP。
动漫插画默认使用 PixAI,通用图的新配置默认使用 GPT。每个用途都能单独修改默认供应商,并为 PixAI、GPT、Gemini 分别填写默认预设 key 和允许的预设。明确说“用 GPT”或“用 Gemini”只覆盖当前请求,不改动持久默认值;关闭或未连接的供应商不会被自动替代。通用图仍需要启用路由与对应模式。
已有的通用图片后端配置继续使用旧路径,直到 owner 明确选择新的供应商。已经创建的 MCP 任务保存原供应商与连接地址;修改默认供应商不会改变旧任务,更换端点时需要先恢复原连接才能恢复任务。
当前 GPT / Gemini 接入支持文生图;不接收参考图片、负面提示词或 seed。供应商已收到请求后的取消能力有限,排查时以平台任务状态为准。费用未知时由平台审批或有次数上限与有效期的可信预设控制;Bot 的日用量额度继续生效。
公开文档的搜索与分享
DOCS_SITE_URL 是可选的构建时配置,填写这份文档对外发布的 HTTPS origin,例如 https://bot.example.com,不要附加 /docs、查询参数或凭据。
使用 Compose 时,在 .env 中设置后重新构建应用:
# .env
DOCS_SITE_URL=https://bot.example.comdocker compose -p cos-bot-prod -f docker-compose.yml -f docker-compose.direct.yml up -d --build直接构建文档时,将变量传给构建命令:
DOCS_SITE_URL=https://bot.example.com pnpm build:docs构建产物为每页生成独立标题和描述、canonical、Open Graph 与 Twitter 分享信息,使用仓库内的 Hanori 分享图片。/docs/sitemap.xml 列出公开文档页;生产服务的 /robots.txt 指向这份 sitemap。切换域名后需要重新构建,仅修改运行时变量不会更新静态页面。
留空时文档仍可匿名阅读和索引,但不输出 canonical 和绝对分享地址,sitemap 为空,不会误用维护者或开发机器的域名。管理面板与登录页始终标记为 noindex, nofollow;这些指令不是访问控制,实际权限仍由服务端认证保证。
部署后检查页面源代码中的 canonical 与 og:image,确认它们指向自己的域名,并确认图片、/robots.txt 和 /docs/sitemap.xml 可匿名访问。搜索收录和社交平台缓存更新由各平台决定,构建成功不代表已经收录。