环境变量配置指南
按领域配置 PureChatNext 本地开发、Vercel 与 Docker 环境变量。
创建环境变量文件
在项目根目录创建 .env.local 文件,并添加以下配置:
# 数据库连接(用于 Drizzle ORM)
# 本地 Docker PostgreSQL(pnpm dev:docker):
DATABASE_DRIVER=node
DATABASE_URL=postgresql://purechat:<URL 编码后的 POSTGRES_PASSWORD>@127.0.0.1:5432/purechat
# 密码需与 docker-compose/dev/.env 中 POSTGRES_PASSWORD 一致
# 云托管 Postgres(Supabase 免费服务、Neon 等)示例:
# DATABASE_DRIVER=neon
# DATABASE_URL=postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
# 连接池(推荐):
# DATABASE_URL=postgresql://postgres.[PROJECT-REF]:[PASSWORD]@aws-0-[REGION].pooler.supabase.com:6543/postgres
# Neon 示例:
# DATABASE_URL=postgresql://user:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require
# 应用对外地址(本地统一 SPA 端口;CORS 默认允许该地址)
APP_URL=http://localhost:5174
# CORS 额外来源,逗号分隔。省略时使用 APP_URL(本地开发端口已内置)
# ALLOWED_ORIGINS=https://www.example.com
# Node 环境
NODE_ENV=development可选:使用 Supabase 或 Neon 免费 Postgres
应用只需要 PostgreSQL 连接串,可将 Supabase 或 Neon 当作免费 Postgres:
- 登录并创建项目
- 复制 Postgres 连接字符串 →
DATABASE_URL- Supabase 直连:
postgresql://postgres:[YOUR-PASSWORD]@db.xxxxx.supabase.co:5432/postgres - Supabase 连接池:
postgresql://postgres.xxxxx:[PASSWORD]@aws-0-[REGION].pooler.supabase.com:6543/postgres - Neon:
postgresql://user:password@ep-xxx.region.aws.neon.tech/dbname?sslmode=require
- Supabase 直连:
- 云托管通常设置
DATABASE_DRIVER=neon
配置说明
APP_URL
应用对外根地址,用作 better-auth baseURL、认证邮件链接、OAuth redirectURI 等。
| 环境 | 推荐值 | 说明 |
|---|---|---|
| 本地开发 | http://localhost:5174 | UI 在 Vite SPA;邮件/OAuth 链接同源,/api 经 Vite 代理到 Next :3000 |
| 生产主站 | https://app.purechat.cn | 主站实例自己的认证、邮件和 OAuth 回调地址 |
| Vercel 备用站 | https://next.purechat.cn | 备用实例自己的认证回调地址;Gateway 功能受运行环境限制 |
APP_URL 表示当前部署实例自己的公开地址,用于认证与回调。主站设置为 https://app.purechat.cn;Vercel 备用实例设置为 https://next.purechat.cn。
SITE_CANONICAL_URL 控制公开页面的 canonical、robots 和 sitemap 地址。主站可以省略(默认使用正式主站地址);Vercel 备用实例设置为 https://app.purechat.cn,这样备用站继续使用自己的认证/邮件回调地址,但搜索引擎将主站视为规范地址。自托管者若使用自己的正式域名,可省略该变量并让它回退到 APP_URL。
Vercel 的生产环境变量需在部署构建前设置并重新部署;robots.txt 和 sitemap 使用静态生成,不能只在部署后修改运行时变量。
Vercel 备用实例还应设置 PURECHAT_DESKTOP_CLOUD_URL=https://app.purechat.cn,避免从备用部署打开桌面登录时将桌面端指回功能受限的 Vercel 站点。
两套部署若要共享账号、配置和对话,必须使用一致的 DATABASE_URL、AUTH_SECRET、KEY_VAULTS_SECRET、兼容的对象存储配置和同一版本数据库迁移;OAuth 提供方与邮件链接还需允许对应回调域名。只保留 next.purechat.cn 的独立数据副本不能构成可用备站。
不要在本地把 APP_URL 设为 http://localhost:3000:邮件点开后会落在 Next 壳而不是 SPA,重置密码 / 验证邮箱体验会错乱。
端口对照:
| 端口 | 角色 | 何时使用 |
|---|---|---|
5174 | Vite SPA(本地 UI) | 浏览器打开站点、APP_URL、邮件落地 |
3000 | Next API / BFF | /api/*、curl 直打接口;不当主站入口 |
3210 | Docker / 本地生产预览 | Docker 回环;或 pnpm preview:prod 同域入口 |
修改后需重启 Next(pnpm dev:next 或 pnpm dev)。
ALLOWED_ORIGINS
CORS 与 Better Auth trustedOrigins 的额外允许来源,逗号分隔。APP_URL 始终会被加入,因此生产环境前后端同域时可以省略;只需在有额外前端域名时再配置。不要使用 *。
本地生产预览
发布前若要在本地跑「生产构建 + 生产密钥」形态:
# 需本机 bun;先准备 .env.production.local(生产 S3 / Redis / DATABASE 等)
pnpm preview:prod
# 已 build 过可跳过构建(仍会校验 .next/BUILD_ID)
pnpm preview:prod -- --skip-build
# 仅在确认目标数据库已迁移后跳过迁移
pnpm preview:prod -- --skip-migrate
# 同时复用已有构建并跳过迁移
pnpm preview:prod -- --skip-build --skip-migrate
# 更换预览端口(也支持 -p 3211 或调用方 PORT=3211)
pnpm preview:prod -- --port 3211preview:prod 会关闭 Bun 默认的 Env 自动加载,再由脚本按 .env → .env.production → .env.local → .env.production.local 的顺序加载 Env 文件,后者覆盖前者,调用命令显式传入的环境变量优先级最高。随后将 APP_URL 覆写为 http://localhost:3210(可用 -p / --port 或调用方 PORT 改端口);CORS 会自动包含该地址。
启动顺序为:校验配置与端口 → 生产构建 → 校验 .next/BUILD_ID → db:migrate → next start → /api/health 就绪检测。迁移失败时不会启动服务;健康检查返回降级或 503 时会醒目告警,但保留已经启动的预览进程供排查。浏览器打开最终打印出的本地 URL(同域 SPA + API)。
警告:默认会迁移并连接生产 DB,也会连接生产 S3 / Redis,迁移和其他写操作可能影响真实数据。db:migrate 可重复安全执行;仅在确认数据库已经与当前代码同步时使用 --skip-migrate。本地 build:spa:copy 还会改写 spaHtmlTemplate.generated.ts,勿提交构建产物。
CODE_INSPECTOR
本地开发可选。设为 1 时,在 Vite SPA(与 Next Turbopack)启用 code-inspector:按住 Alt+Shift 点击页面元素,在 Cursor 中打开对应源码。
- 默认关闭(降低编译与内存开销)
- 临时开启推荐:
pnpm dev:inspect(等价于CODE_INSPECTOR=1 pnpm dev,完整 Next + SPA) - 也可写入
.env.local:CODE_INSPECTOR=1后重启开发进程
VITE_DEVTOOLS
本地开发可选。设为 1 时,在 Vite SPA 启用 @vitejs/devtools(嵌入式浮动面板;vite build 时还会开启 Rolldown devtools 并写出分析产物)。
- 默认关闭
- 临时开启:
VITE_DEVTOOLS=1 pnpm dev:spa(或写入.env.local后重启) - 生产构建请勿开启(避免把 DevTools 产物打进
public/_spa)
VITE_SPA_UPDATE_PREVIEW
本地开发可选。设为 1 时,SPA 会在进入页面后立刻弹出「检测到系统有新版本」提示,用于核对样式与「立即刷新 / 稍后再说」。
- 默认关闭(开发环境本来就不会做部署指纹检测)
- 临时开启:
VITE_SPA_UPDATE_PREVIEW=1 pnpm dev:spa(或写入.env.local后重启) - 也可不改 env:浏览器打开任意 SPA 路径并加上
?spaUpdatePreview=1
ALLOWED_ORIGINS
允许跨域请求的源地址。在生产环境中,应该设置为你的实际域名。
示例:
- 开发环境:
http://localhost:3000,http://localhost:5174(需同时包含 Next 与 SPA) - 生产环境:
https://yourdomain.com,https://www.yourdomain.com
GITHUB_PROXY
可选。GitHub 下载镜像前缀,例如 https://ghfast.top/。技能安装拉仓库文件、以及技能头像等静态图都会先走该前缀,失败再回 GitHub 源站。浏览器不会直连 github.com 拉图,而是请求同源 /api/proxy/github-asset。
- 未设置时:图片会同时尝试
avatars.githubusercontent.com、wsrv.nl 和原始地址;技能安装只直连 GitHub - 国内自托管建议设置(格式为
https://example/+ 原始 GitHub URL) - 海外(如 Vercel)可省略
DATABASE_URL
PostgreSQL 数据库连接字符串,用于 Drizzle ORM 迁移和数据库操作。
- 本地 Docker:
postgresql://purechat:<URL 编码后的 POSTGRES_PASSWORD>@127.0.0.1:5432/purechat(密码以docker-compose/dev/.env为准) - 云托管(Supabase 免费 Postgres、Neon 等):
postgresql://postgres:[密码]@db.[项目引用].supabase.co:5432/postgres - 生产 Docker:
install.sh在宿主机 PostgreSQL 中创建用户和数据库purechat,Compose 注入postgresql://purechat:…@<容器名>:5432/purechat。不要把连接串写成公网域名。 - 云托管常支持直连(5432)或连接池(6543);本地实例使用 5432
DATABASE_DRIVER
控制 postgres-js 是否强制启用 SSL:
- 云托管 PostgreSQL(Supabase、Neon 等):
DATABASE_DRIVER=neon - 本机或明确无需 SSL 的 PostgreSQL:
DATABASE_DRIVER=node
本地 Docker 启停与连接说明见 本地 PostgreSQL 管理。
KEY_VAULTS_SECRET
敏感配置加密密钥(AES-256-GCM)。用于微信 / QQ 渠道凭证与 context_token,以及用户在设置页保存的服务商 API Key / 代理地址。生成:openssl rand -base64 32。未配置时无法加密保存用户密钥,渠道绑定也会失败。
Docker 内部服务地址
开发时从宿主机运行应用,因此 PostgreSQL、Redis、RustFS 与 SearXNG 使用 127.0.0.1 加映射端口(见 pnpm dev:docker)。生产只运行应用容器:PostgreSQL 与 Redis 使用宿主机已有实例(install.sh 将应用加入共享 Docker 网络,主机名为容器名);文件与搜索走云端配置。
生产密钥与内部 URL 由 pnpm docker:setup:deploy 或离线包里的 install.sh 生成,不要把 docker-compose/deploy/.env 提交到仓库。默认应用 2g 资源档案,见 云服务器部署。完整说明见 Docker 自托管与数据迁移。
云服务器改完 /opt/purechat/docker-compose/deploy/.env 后必须重建容器,docker restart / 1Panel「重启」无效:
sudo ./install.sh up --force-recreateS3 对象存储
资源库文件、头像等依赖 S3 兼容存储(AWS S3、RustFS、MinIO 等)。相关变量定义在 packages/env/src/file.ts,示例见根目录 .env.example。
| 变量 | 说明 |
|---|---|
S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY | 访问密钥 |
S3_BUCKET | 桶名 |
S3_ENDPOINT | API 端点(本地 RustFS 一般为 http://localhost:9000) |
S3_PUBLIC_DOMAIN | 浏览器访问用的自定义域名(如 https://cdn.example.com);不能当作 S3_ENDPOINT |
S3_REGION | 区域;本地可填 us-east-1 |
S3_ENABLE_PATH_STYLE | 1 时使用 path-style(endpoint/bucket/key);RustFS / MinIO 通常需要 |
S3_SET_ACL | 是否上传时设置对象 public-read ACL(见下) |
S3_PREVIEW_URL_EXPIRE_IN | 预签名 URL 过期秒数,默认 7200 |
FILE_STORAGE_LIMIT_MB | 单用户存储额度(MB),默认 15 |
本地 Docker RustFS(pnpm dev:docker)推荐与 docker-compose/dev/.env 中 RUSTFS_* 对齐:
S3_ACCESS_KEY_ID=<docker-compose/dev/.env 中的 RUSTFS_ACCESS_KEY>
S3_SECRET_ACCESS_KEY=<docker-compose/dev/.env 中的 RUSTFS_SECRET_KEY>
S3_BUCKET=purechat
S3_ENDPOINT=http://localhost:9000
S3_ENABLE_PATH_STYLE=1
S3_SET_ACL=0生产 Docker 请填写对象存储服务的 Endpoint 与密钥,不要使用上述 localhost 地址。
腾讯云 COS
用 @aws-sdk/client-s3 访问 COS 时,S3_ENDPOINT 必须是地域 API 地址,不能填自定义源站 / CDN 域名:
S3_ACCESS_KEY_ID=<CAM SecretId>
S3_SECRET_ACCESS_KEY=<CAM SecretKey>
S3_BUCKET=<bucket>-<APPID>
S3_ENDPOINT=https://cos.ap-shanghai.myqcloud.com
S3_REGION=ap-shanghai
S3_ENABLE_PATH_STYLE=0
S3_SET_ACL=0SDK 会按 virtual-hosted 访问 https://<bucket>.cos.<region>.myqcloud.com。cdn.example.com 这类自定义域名只用于浏览器下载,PutObject / ListObjects 仍走上面的 API 地址。应用侧已关闭默认 CRC32 校验(COS 不支持)。
头像走自定义域名时额外设置:
S3_PUBLIC_DOMAIN=https://cdn.purechat.cn并在 COS 桶策略中允许匿名 GetObject(至少 user/avatar/*)。对象仍私有时浏览器会 403,此时不要设 S3_PUBLIC_DOMAIN,头像会回退到同域代理 /api/webapi/user/avatar/...。
S3_SET_ACL
控制上传时是否给对象打 public-read ACL,以及客户端如何拿到文件 URL。
| 值 | 上传行为 | 访问方式 |
|---|---|---|
1 | PutObject / 预签名上传带 ACL: public-read | 客户端直接使用 S3 公网 URL |
0 | 不设置 ACL,对象保持私有 | 资源经应用代理;头像在设置了 S3_PUBLIC_DOMAIN 时走自定义域名,否则走 /api/webapi/user/avatar/... |
推荐:
- 本地 RustFS / Docker 生产 / 私有桶:固定
S3_SET_ACL=0(多数兼容存储不支持或不建议对象级 ACL;生产 Compose 也不会开放匿名读桶) - 云上公开直链:仅当桶策略允许对象级
public-read,且你确实需要浏览器直链访问时再设S3_SET_ACL=1
修改后需重启 Next(及依赖 S3_* 的 Gateway 等进程)。
NODE_ENV
运行环境,通常为 development 或 production。
微信 iLink 渠道
见 微信渠道。KEY_VAULTS_SECRET 为必填。回复使用用户在设置页保存的服务商密钥,不读取 OPENAI_API_KEY / DEEPSEEK_API_KEY。本地需显式设置 CHANNEL_GATEWAY_ENABLED=1;Docker 在单一 Next 容器内启用;Vercel 不支持。
QQ 开放平台渠道
见 QQ 渠道。协议层在 @pure/chat-adapter/qq。凭证按绑定加密存储;WebSocket 由开启后的 Next Server 内置 Gateway 维护,Webhook 继续使用公网回调与平台验证。Vercel 仅支持 Webhook。
安全提示
⚠️ 重要:
.env.local文件已添加到.gitignore,不会被提交到 Git- 不要在生产环境中使用
NEXT_PUBLIC_*前缀暴露敏感信息 ALLOWED_ORIGINS不要在生产环境中使用*DATABASE_URL包含敏感数据库密码,切勿提交到版本控制系统