跳到主要内容

部署

AISCouncil 作为静态文件部署在 Cloudflare Pages 上,API 逻辑运行在 Cloudflare Workers 上。统一的部署脚本处理所有目标。

部署目标

目标URL类型命令
应用aiscouncil.netCF Pages(静态)scripts/deploy.sh pages
预发布aiscouncil.netCF Pages(静态)scripts/deploy.sh pages-staging
API Workerapi.aiscouncil.netCF Workerscripts/deploy.sh worker
身份验证 Workerauth.aiscouncil.netCF Workerscripts/deploy.sh worker-auth
应用商店store.aiscouncil.netCF Pages(静态)scripts/deploy.sh store
全部以上所有所有scripts/deploy.sh all

环境变量

~/.bashrc 中导出这些(永远不要提交它们):

export CF_ACCOUNT_ID_AISCOUNCIL="your-cloudflare-account-id"
export CF_PAGES_TOKEN_AISCOUNCIL="your-pages-api-token"
export CF_WORKER_TOKEN_AISCOUNCIL="your-worker-api-token"

可选覆盖:

export CF_PAGES_PROJECT_AISCOUNCIL="aiscouncil"              # 默认
export CF_PAGES_PROJECT_AISCOUNCIL_STAGING="aiscouncil-staging" # 默认
注意

这些令牌授予对您 Cloudflare 账户的部署访问权限。永远不要将它们提交到仓库。如果缺少必需变量,部署脚本将退出并显示错误。

Pages 部署(生产)

分步

  1. 从源代码组装应用程序:
./build.sh
  1. 部署到生产环境:
scripts/deploy.sh pages

此命令:

  • 创建干净的 _deploy/ 目录
  • 通过 rsync 复制静态文件,排除开发产物
  • 使用 html-minifier-terser 压缩 index.html(约 40% 大小减少)
  • 使用 --branch=main 部署到 Cloudflare Pages
  • 清理 _deploy/
信息

生产部署始终使用 --branch=main。这是 CF Pages 在生产域(aiscouncil.net)上提供服务所必需的。

部署什么

rsync 步骤排除所有不是面向浏览器的资产:

排除的目录: src/, tools/, kernel/, serve/, worker/, worker-auth/, doc.aiscouncil.net/, node_modules/, .git/, .github/, .carl/, .claude/, modules/, scripts/, core-types/, bridge/, i18n/, dist/, build/

排除的文件类型: *.py, *.zig, *.zon, *.md, *.sh, *.css, .env*

排除的配置文件: package.json, package-lock.json, vitest.config.*, tsconfig.json, .cfignore, .gitignore

剩下的是生产资产:index.html, sw.js, 图标, manifest.webmanifest, registry/ JSON 文件, sdk/, ads.json, sitemap.xml, 以及任何小程序或应用目录。

压缩

生产部署通过 html-minifier-terser 传递 index.html,使用这些选项:

  • 折叠空白
  • 删除注释
  • 删除冗余属性
  • 折叠布尔属性
  • 压缩内联 CSS
  • 压缩内联 JavaScript

典型大小减少约 40%(例如 980 KB 降至约 580 KB)。

预发布部署

无需压缩部署到预发布环境:

scripts/deploy.sh pages-staging

预发布从 aiscouncil.net 提供。应用程序在运行时自动检测其域,并相应调整 API URL、cookie 域和跨源引用。

将预发布提升为生产

在预发布上验证后,将相同的构建提升到生产:

scripts/deploy.sh promote

这将使用启用的压缩将当前代码重新部署到生产 Pages 项目。应用程序代码相同 —— 只有域更改。

Worker 部署

API Worker

scripts/deploy.sh worker

这使用您环境中的账户 ID 和 Worker 令牌在 worker/ 目录内运行 npx wrangler deploy

身份验证 Worker

scripts/deploy.sh worker-auth

对于 worker-auth/ 目录的相同过程。

Worker 密钥

Worker 需要与代码部署分开设置的密钥。从 worker 目录使用 wrangler secret put

cd worker
npx wrangler secret put JWT_SECRET
npx wrangler secret put STRIPE_SECRET_KEY
npx wrangler secret put STRIPE_WEBHOOK_SECRET
npx wrangler secret put WEBHOOK_PATH_SECRET
cd worker-auth
npx wrangler secret put JWT_SECRET
npx wrangler secret put GOOGLE_CLIENT_SECRET
npx wrangler secret put APPLE_CLIENT_SECRET
npx wrangler secret put GITHUB_CLIENT_SECRET
提示

密钥在部署之间持久存在。您只需设置一次,或在轮换凭证时设置。

Worker 配置

每个 worker 都有一个 wrangler.toml,定义:

  • Worker 名称和路由
  • KV 命名空间绑定
  • 环境变量引用
  • 兼容性设置

Service Worker 缓存

客户端 Service Worker(sw.js)使用版本化缓存:

const CACHE = "ais-v1.0.0";

何时提升缓存版本:

  • 应用程序 shell 的重大更改(HTML 结构、关键 CSS)
  • 预缓存资产的更改(图标、清单)
  • 主要版本发布

提升版本会导致 Service Worker:

  1. 使用新名称创建新缓存
  2. 预缓存所有列出的资产
  3. 激活时删除所有旧缓存
注意

在重大更改后忘记提升缓存版本将导致用户看到过时内容,直到他们手动清除浏览器缓存或旧 Service Worker 过期。

部署所有内容

按顺序部署 Pages 应用程序、API worker 和身份验证 worker:

scripts/deploy.sh all

部署后验证

部署后,验证应用程序是否正确提供服务:

# 检查生产
curl -s https://aiscouncil.net/ | head -5

# 检查 API 健康状态
curl -s https://api.aiscouncil.net/health

# 检查身份验证健康状态
curl -s https://auth.aiscouncil.net/health
信息

Cloudflare Pages 在部署时自动使其 CDN 缓存失效,但全球传播可能需要 1-2 分钟。如果您看到过时内容,请稍等片刻再试。

域架构

应用程序在运行时使用域检测来支持生产和预发布:

常量生产预发布
应用AIS.DOMAINaiscouncil.netaiscouncil.net
营销AIS.WWWwww.aiscouncil.netwww.aiscouncil.net
APIAPI_BASEhttps://api.aiscouncil.net/v1https://api.aiscouncil.net/v1
身份验证AUTH_BASEhttps://auth.aiscouncil.net/v1https://auth.aiscouncil.net/v1
文档AIS.DOC_BASEhttps://doc.aiscouncil.nethttps://doc.aiscouncil.net
商店AIS.STORE_URLhttps://store.aiscouncil.nethttps://store.aiscouncil.net

API 基础 URL 也可以通过 localStorage 为本地开发覆盖:

localStorage.setItem("ais-api-base", "http://localhost:8787/v1");
localStorage.setItem("ais-auth-base", "http://localhost:8788/v1");

本地开发

对于不部署的本地开发:

  1. 构建应用程序:./build.sh
  2. 使用任何静态文件服务器提供 index.html(例如 python3 -m http.server 8080
  3. 使用 Wrangler 本地运行 Worker:
cd worker && npx wrangler dev
cd worker-auth && npx wrangler dev --port 8788
  1. 在浏览器控制台中覆盖 API 基础 URL:
localStorage.setItem("ais-api-base", "http://localhost:8787/v1");
localStorage.setItem("ais-auth-base", "http://localhost:8788/v1");
location.reload();