1wrangler.toml 绑定(workers/gateway)
name = "aigw-gateway"
main = "src/index.ts"
compatibility_date = "2026-05-30"
compatibility_flags = ["nodejs_compat"]
[[d1_databases]]
binding = "DB"
database_name = "aigw-prod-db"
database_id = "<prod-d1-id>"
[[kv_namespaces]]
binding = "CACHE"
id = "<prod-kv-id>"
[durable_objects]
bindings = [{ name = "RATE_LIMITER", class_name = "RateLimiter" }]
[[migrations]]
tag = "v1"
new_classes = ["RateLimiter"]
[[queues.producers]]
binding = "BATCH_QUEUE"
queue = "aigw-prod-batch"
[ai]
binding = "AI" # Workers AI
[vars]
ENVIRONMENT = "prod"
AI_GATEWAY_ACCOUNT = "<cf-account-id>"
AI_GATEWAY_NAME = "aigw" # Cloudflare AI Gateway 名
# --- 预览环境覆盖 ---
[env.preview]
[env.preview.vars]
ENVIRONMENT = "preview"
# preview 用各自的 d1/kv id(CI 注入或单独 toml)
# secrets 不写在此(用 wrangler secret / GitHub Secrets),见下
2环境变量与 secrets
| 名称 | 类型 | 用途 |
|---|---|---|
| ENVIRONMENT | var | dev/preview/prod |
| AI_GATEWAY_ACCOUNT / AI_GATEWAY_NAME | var | Cloudflare AI Gateway 路由 |
| OPENROUTER_API_KEY | secret | OpenRouter 渠道 |
| DEEPSEEK_API_KEY / GROQ_API_KEY | secret | 直采渠道 |
| ADMIN_TOKEN | secret | 管理端鉴权 |
| KEY_HASH_PEPPER | secret | api_key 哈希加盐 |
# 本地:.dev.vars(在 .gitignore 内,绝不提交)
OPENROUTER_API_KEY="sk-or-..."
DEEPSEEK_API_KEY="sk-..."
ADMIN_TOKEN="..."
KEY_HASH_PEPPER="..."
# 生产/预览:wrangler secret(或 CI 用 CLOUDFLARE_API_TOKEN 注入)
wrangler secret put OPENROUTER_API_KEY --env preview
wrangler secret put OPENROUTER_API_KEY # prod
⚠️ 铁律
任何上游真实 key、ADMIN_TOKEN、pepper 绝不入仓、绝不下发到调用方、绝不打日志。channels.secret_ref 只存 secret 名(见 22)。
3CI/CD 流水线(.github/workflows/ci.yml)
name: ci
on:
pull_request: {}
push: { branches: [main] }
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test # vitest(含 Miniflare 集成)
- run: pnpm redline:check # 红线脚本:扫描非白名单 provider 引用(见 26)
deploy-preview:
needs: quality
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile
- run: npx wrangler deploy --env preview
env: { CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} }
deploy-prod:
needs: quality
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- run: pnpm install --frozen-lockfile
- run: npx wrangler d1 migrations apply aigw-prod-db --remote
- run: npx wrangler deploy
env: { CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} }
GitHub Secrets 需配 CLOUDFLARE_API_TOKEN(带 Workers/D1/Pages 编辑权限)。secrets 同步用 wrangler secret 手动或专用 job。
4D1 迁移
- 迁移文件放
packages/db/migrations/000X_*.sql,按序号递增、只增不改(已应用的不改)。 - 本地:
wrangler d1 migrations apply aigw-dev-db --local。 - 生产:CI 在 deploy-prod 前
--remote应用;破坏性变更需先备份(wrangler d1 export)。 - 回滚以"新增补偿迁移"为主,不就地回退已上线 schema。
5部署与回滚 runbook
| 场景 | 操作 |
|---|---|
| 常规发布 | 合并到 main → CI 自动迁移 + 部署 prod |
| 快速回滚(代码) | wrangler rollback(回上一个 Worker 版本)或 revert 提交重跑 CI |
| 渠道故障 | 管理端 PATCH /admin/channels/:id {enabled:false},路由自动绕过(无需发版) |
| 成本突增 | 临时调低相关逻辑模型 multiplier / 降配额 / 切到更便宜渠道(改配置) |
| key 泄露 | DELETE /admin/keys/:id 吊销 + 轮换上游 secret(wrangler secret put) |
| 限流误伤 | 调高该 key rpm_limit(管理端)或临时放宽 |
✅ 设计红利
渠道/路由/配额/倍率都是配置(D1),大部分运维动作改配置即生效、无需发版。只有代码逻辑变更才走 CI/CD。