有域名的人,经常会遇到一个小需求:想开几个自己的邮箱地址,比如 hi@example.com、admin@example.com、support@example.com,用来注册服务、收验证码、做个人项目入口。买一整套企业邮箱有点重,自己维护邮件服务器又麻烦。
Cloud Mail 走的是另一条路:把邮箱服务部署到 Cloudflare Workers,前端是 Vue3,后端用 Hono,数据放在 D1 和 KV,附件放到 R2 。它更像一个轻量邮箱控制台,适合个人站点、小团队、临时项目邮箱、验证码接收和简单通知场景。
项目地址: https://github.com/maillab/cloud-mail

Cloud Mail 支持收信、发信、附件收发、邮件查询、用户和权限管理。接收邮件后,可以转发到 Telegram 机器人,也可以转发到其他邮箱。后台里还能看系统数据、用户邮件增长和部分统计图。
发信部分集成 Resend,也支持 Cloudflare 的发送能力配置。附件依赖 R2 对象存储。验证码识别用 Workers AI,收到邮件后可以自动提取验证码。对经常注册服务、管理多个项目邮箱的人,这个功能很实用。

部署前准备
先准备这些东西:
- • 一个已经接入 Cloudflare 的域名;
- • 一个 Cloudflare 账号;
- • Cloudflare API Token,需要 Workers 、 D1 、 KV 、 R2 相关权限;
- • 一个 D1 数据库;
- • 一个 KV 命名空间;
- • 如果要收发附件,再准备一个 R2 Bucket;
- • 一个管理员邮箱,比如
admin@example.com; - • 一段随机的
JWT_SECRET,后面初始化数据库会用到。
项目有两种部署方式。新手建议先用 GitHub Actions,因为仓库里已经写好了工作流,改 Secrets 后手动运行即可。熟悉 Wrangler 的人,也可以本地部署。
方法一:用 GitHub Actions 部署
第一步,Fork 仓库:
https://github.com/maillab/cloud-mail
第二步,进入 GitHub 仓库的 Settings -> Secrets and variables -> Actions,新增这些变量:
CLOUDFLARE_API_TOKEN=你的 Cloudflare API Token
CLOUDFLARE_ACCOUNT_ID=你的 Cloudflare Account ID
D1_DATABASE_ID=你的 D1 数据库 ID
KV_NAMESPACE_ID=你的 KV 命名空间 ID
R2_BUCKET_NAME=你的 R2 Bucket 名称
DOMAIN=["example.com"]
ADMIN=admin@example.com
JWT_SECRET=一段足够长的随机字符串
CUSTOM_DOMAIN=mail.example.com
DOMAIN 要写成 JSON 数组。即使只有一个域名,也要保留英文双引号和方括号:
["example.com"]
如果不使用附件,可以先不填 R2_BUCKET_NAME。如果不绑定自定义访问域名,可以先不填 CUSTOM_DOMAIN,部署后用 Workers 默认域名测试。
第三步,到 GitHub Actions 页面,手动运行 Deploy cloud-mail to Cloudflare Workers。工作流会安装依赖、生成 Wrangler 配置、创建或绑定 D1/KV,然后部署 Worker 。
部署成功后,打开:
https://你的访问域名/api/init/你的JWT_SECRET
页面返回 success,说明数据库表已经初始化。之后访问你的站点域名,就能进入 Cloud Mail 前端。

方法二:本地用 Wrangler 部署
本地部署适合需要改代码或自己接 CI 的人。先安装依赖:
git clone https://github.com/maillab/cloud-mail.git
cd cloud-mail/mail-worker
pnpm install
然后编辑 mail-worker/wrangler.toml,至少要补上 D1 、 KV 、域名和管理员信息:
[[d1_databases]]
binding = "db"
database_name = "cloud-mail"
database_id = "你的 D1_DATABASE_ID"
[[kv_namespaces]]
binding = "kv"
id = "你的 KV_NAMESPACE_ID"
[[r2_buckets]]
binding = "r2"
bucket_name = "你的 R2_BUCKET_NAME"
[vars]
domain = ["example.com"]
admin = "admin@example.com"
jwt_secret = "一段随机字符串"
前端构建产物会输出到 mail-worker/dist,仓库里的构建命令已经写在 Wrangler 配置里:
[build]
command = "pnpm --prefix ../mail-vue install && pnpm --prefix ../mail-vue run build"
确认配置后部署:
pnpm wrangler deploy
部署完同样要访问初始化地址:
https://你的访问域名/api/init/你的JWT_SECRET
域名和收信怎么接
Cloud Mail 需要 Cloudflare 接管域名。大致流程是:
- 1. 在 Cloudflare 里把域名接入并完成 DNS 托管;
- 2. 给 Worker 绑定访问域名,比如
mail.example.com; - 3. 配置 Cloudflare Email Routing,把目标邮箱域名的邮件交给对应 Worker 处理;
- 4. 登录 Cloud Mail 后台,创建用户、邮箱账号和角色权限;
- 5. 如果要发信,在后台配置 Resend Token,或按自己的 Cloudflare 发送方案处理。
这里要分清两个域名概念:mail.example.com 是后台访问地址,example.com 是邮箱后缀。前者给人打开网页,后者负责收发邮件。

后台里先改哪些配置
第一次进后台,建议先做四件事。
先确认管理员邮箱。ADMIN 对应的邮箱拥有最高权限,不要随便换。再创建普通用户和邮箱账号,按角色限制能用哪些域名、每天能发多少封。
接着配置附件存储。如果要发附件和内嵌图片,需要 R2 正常可用,并设置对象访问域名。没有 R2 时,普通收信可以测试,附件功能会受限。
然后配置发信。 Cloud Mail 的 README 写明集成 Resend,后台里可以配置 Resend Token 。发信域名还需要在 Resend 侧完成 DNS 验证,否则只能收信,不能稳定发信。
最后打开 Telegram 推送。把 Bot Token 和 Chat ID 填好,收到验证码邮件时,手机上能直接看到提醒。

适合什么场景
Cloud Mail 适合低频、轻量、可控的邮箱需求。比如个人域名邮箱、项目测试邮箱、临时验证码收件箱、小团队内部通知邮箱。
它不适合替代大型企业邮箱。高并发群发、复杂反垃圾策略、长期邮件归档、跨地区合规审计,这些不是它的主战场。把它当作一个跑在 Cloudflare 上的轻量邮箱后台,会更符合它的设计。
如果你已经把域名放在 Cloudflare,Cloud Mail 的上手成本不高。先用 GitHub Actions 跑通收信,再补 R2 、 Resend 和 Telegram 推送。跑通以后,一个域名就能拆出多个邮箱地址,后台统一管理,成本也比较轻。
阅读原文:https://mp.weixin.qq.com/s/nS7MwR_joe0uNpy1MS3oYQ
该文章在 2026/6/23 11:47:52 编辑过