# Cloudflare 部署设计(v2,docs/11 §12) ## 服务 使用 Cloudflare Workers、Email Workers / Email Routing、D1、R2、Cron Triggers、OAuth; Queues 在需要可靠异步投递时再加入,并以当前 Cloudflare 限制为准。 ## Console Console 本身部署在 Cloudflare Workers: ```text Worker +-- Frontend Assets +-- Management API +-- /internal/email/authorize + /internal/email/ingest(Email Worker 专用) +-- OAuth Callback +-- Cron Handler ``` 部署步骤:`bunx wrangler d1 create wmailhub` -> `wrangler r2 bucket create` -> `wrangler d1 execute wmailhub --remote --file=./migrations/0001_init.sql`(以及 0002/0003)-> `wrangler secret put SESSION_SECRET` -> 配置 CF_OAUTH_CLIENT_ID/SECRET/REDIRECT_URI vars。 PUBLIC_BASE_URL 即 Email Worker 里的 CONSOLE_URL。 ## Email Routing 与 catch-all Worker(动态邮箱) 动态邮箱场景把域名邮件通过 catch-all 规则交给 WmailHub Email Worker: ```text *@example.com | v WmailHub Email Worker -> Console(authorize) +-- accept -> ingest +-- reject -> message.setReject() ``` 这样即使 unknown@example.com 在 Console 中不存在,也会进入 Worker, 由 Console 判断后执行 `message.setReject()`。如果只为现有邮箱创建 literal routing, 不存在的地址可能根本不会进入 Worker,WmailHub 无法完成 SMTP 阶段拒绝。 Console 的「域名 -> 设置 Email Workers」会自动完成:开启 Email Routing + catch-all 指向 Worker。 ## Email Worker 账号级一个 Worker(名字 wmailhub-email-),脚本由 Console 自动上传, 内含 CONSOLE_URL / WORKER_ID / WORKER_SECRET;只做 authorize + ingest + setReject, 不保存业务数据。 ## R2 ```text emails/{yyyy}/{mm}/{dd}/{email_id}/raw.eml emails/{yyyy}/{mm}/{dd}/{email_id}/attachments/{attachment_id} ``` ## D1 保存 cloudflare_accounts、domains、mailboxes、emails、email_attachments、 webhook_deliveries、oauth_connections、worker_credentials、users、settings、api_credentials、 nonces、oauth_states。 ## Cron 至少实现 cleanup job(过期邮件 + orphan + nonce/state 清理),建议每 15 分钟一次; webhook 重试每 1 分钟,具体以当前 Cloudflare 限制调整。