部署网站
准备远程资源、执行 Production dry-run,并将 Tanplate 部署到 Cloudflare Workers。
本文档说明如何把 Tanplate 的 Web、Admin 和 Docs 应用部署到 Cloudflare Workers。实际选中的 Worker 和资源由 project.manifest.json 决定。
Production 是受控人工流程
仓库的规划命令只生成 dry-run,不会创建资源、写 secret、执行 migration
或部署。Production 操作必须按 ai-docs/production-runbook.md
展示目标、获得在场批准,并在每一步后验证。
部署前准备
开始前确认:
- 已按 快速开始 完成本地初始化和运行。
- 已按 环境配置 配置当前 Profile 所需的变量、secret 名称和 binding。
- 已登录获授权的 Cloudflare 账号,并准备最小权限 API Token。
- 生产域名、Worker 名称、D1/R2/Queue 等资源归属已经明确。
- 工作区通过
pnpm verify。
Wrangler 构建后会显示 Worker 的上传大小和压缩大小。Cloudflare 的套餐限制可能变化,发布前应以 Workers limits 为准。
部署步骤
1. 配置项目身份
在 project.manifest.json 设置项目 slug、生产 URL、品牌和要部署的应用:
{
"apps": {
"admin": { "deploy": true },
"docs": { "deploy": true },
"web": { "deploy": true }
},
"project": {
"baseUrl": "https://example.com",
"name": "Example",
"slug": "example"
}
}然后重新生成并检查受管配置:
pnpm init:template
pnpm check:template2. 生成部署计划
Local 计划可直接运行:
pnpm plan:deployment -- --target localProduction 计划必须声明 production ref、部署变量名和所需 secret 名称。下面是 Authentication Profile 的示例:
pnpm plan:deployment -- \
--target production \
--ref refs/heads/main \
--production-ref main \
--variable CLOUDFLARE_ACCOUNT_ID \
--secret deployment:CLOUDFLARE_API_TOKEN \
--secret web:BETTER_AUTH_SECRET \
--secret web:GOOGLE_CLIENT_ID \
--secret web:GOOGLE_CLIENT_SECRET \
--secret web:GITHUB_CLIENT_ID \
--secret web:GITHUB_CLIENT_SECRET \
--secret web:RESEND_API_KEY \
--secret web:TURNSTILE_SECRET_KEY \
--secret admin:BETTER_AUTH_SECRET以上参数对应仓库当前启用 Google/GitHub Social Auth 且部署 Admin 的 Profile;修改 Manifest 后,应按 dry-run 的 requirements 增删名称。输出包含 selected apps、资源清单、migration/secret/deploy 前置步骤和 blocked reasons。所有步骤固定为 executable=false,命令参数只包含名称,不包含 secret 值。
3. 准备远程资源
根据计划只创建当前 Profile 的真实消费者需要的资源:
- Web 固定部署;Admin 和 Docs 由 Manifest 选择。
- Web/Admin 同时消费数据时共享目标环境 D1。
- Projects 与 User Assets 使用相互隔离的 R2 bucket。
- Jobs 使用 Queue 和原生 DLQ;Product AI 使用 Workers AI binding。
- Docs 不绑定业务 D1、R2 或 AI。
资源创建、远程 D1 migration 和管理员 bootstrap 的命令与检查点以 ai-docs/production-runbook.md 为准。不要从本地状态复制 Production 数据库或 R2 对象。
4. 配置生产变量与 secret
公开变量和 binding 写入对应应用的 wrangler.jsonc。secret 通过获授权的 Cloudflare 流程写入各自 Worker:
- Web:Auth、Social Auth、Resend、Turnstile 等当前 Profile 所需 secret。
- Admin:与 Web 一致的
BETTER_AUTH_SECRET。 - 部署环境:
CLOUDFLARE_ACCOUNT_ID与CLOUDFLARE_API_TOKEN。
Preview 和 Production 使用独立的 origin、secret 与隔离资源。Web 的 Google/GitHub 凭据不得复制到 Admin。
5. 构建与 dry-run
先运行完整验证,再分别查看三个应用的部署选择:
pnpm verify
node scripts/deploy-app.mjs --app web --dry-run
node scripts/deploy-app.mjs --app admin --dry-run
node scripts/deploy-app.mjs --app docs --dry-run构建会删除 dist 中的 .dev.vars / .env*,并扫描构建产物和 Git tracked 文件中的本地 secret 值。命中时只报告文件和变量名,不打印值。
6. 部署 Worker
完成 runbook 中的批准和远程准备后,按应用部署:
pnpm deploy:web
pnpm deploy:admin
pnpm deploy:docs公开部署命令会再次读取根 Manifest,拒绝生成快照漂移,并在真实部署前执行受管配置检查。Manifest 中 deploy=false 的 Admin 或 Docs 会明确跳过。
自定义域名
域名已经托管在 Cloudflare 时,可以通过 Cloudflare Dashboard 绑定 Worker 自定义域名,或在对应 wrangler.jsonc 中添加明确的 routes 配置:
{
"routes": [
{
"pattern": "example.com",
"custom_domain": true
}
]
}同步更新 project.baseUrl、BETTER_AUTH_URL、WEB_ORIGIN 和 OAuth Provider 回调地址。域名尚未托管时,先部署到 workers.dev 验证,再单独完成 DNS 与域名绑定。
自动化边界
GitHub Actions 只运行不接触 Production 凭据的环境预检、构建和本地 Worker E2E。当前仓库不在 CI 中自动执行 Production 资源创建、migration、secret 写入或部署;这些操作保留在人工 runbook 中。
部署后检查
- 验证 Web、Admin、Docs 健康状态与公开页面。
- 验证 Auth origin、Session、邮件和 Turnstile(若启用)。
- 验证 Admin role/permission/ban 与 audit。
- 验证 Projects/User Assets 的 D1/R2 一致性。
- 记录 Worker 版本和远程 migration 状态,确认恢复路径可用。
更完整的资源和 Preview 生命周期说明见 Cloudflare。