364 lines
7.1 KiB
Markdown
364 lines
7.1 KiB
Markdown
# cf-temp-email
|
||
|
||
Cloudflare Temp Email 的自动化部署 CLI。它会编排 Cloudflare REST API、`npm` 和 `wrangler`,统一处理以下资源:
|
||
|
||
- Pages
|
||
- Worker
|
||
- D1
|
||
- Email Routing
|
||
- Catch-all 到 Worker
|
||
|
||
适用场景:
|
||
|
||
- 从零部署一套 Cloudflare Temp Email
|
||
- 用一个 `config.toml` 管多个 Cloudflare 账号
|
||
- 从 Cloudflare 现有资源反推配置,再继续接管部署
|
||
|
||
## 快速开始
|
||
|
||
在 `cftemail/` 目录下执行:
|
||
|
||
```bash
|
||
uv sync
|
||
uv run cf-temp-email init-config --config config.toml
|
||
uv run cf-temp-email check --config config.toml
|
||
uv run cf-temp-email deploy --config config.toml
|
||
```
|
||
|
||
省略子命令时默认执行 `deploy`,所以:
|
||
|
||
```bash
|
||
uv run cf-temp-email --config config.toml
|
||
```
|
||
|
||
等价于:
|
||
|
||
```bash
|
||
uv run cf-temp-email deploy --config config.toml
|
||
```
|
||
|
||
## 命令
|
||
|
||
可用命令:
|
||
|
||
- `init-config`
|
||
- `check`
|
||
- `deploy`
|
||
- `resume`
|
||
- `discover-config`
|
||
|
||
常用示例:
|
||
|
||
```bash
|
||
uv run cf-temp-email check --config config.toml --profile kotei
|
||
uv run cf-temp-email deploy --config config.toml --profile kotei
|
||
uv run cf-temp-email resume --config config.toml --profile kotei
|
||
```
|
||
|
||
### `discover-config`
|
||
|
||
用于从 Cloudflare 现有资源反推配置,并写回 `config.toml`。
|
||
|
||
示例:
|
||
|
||
```bash
|
||
uv run cf-temp-email discover-config \
|
||
--config config.toml \
|
||
--profile kotei \
|
||
--api-token "$CF_API_TOKEN_KOTEI" \
|
||
--zone-name "kotei.us.ci"
|
||
```
|
||
|
||
当前能自动发现并写入的字段包括:
|
||
|
||
- `cloudflare.account_id`
|
||
- `cloudflare.account_name`
|
||
- `cloudflare.zone_name`
|
||
- `mail.domains`
|
||
- `mail.verified_destination_address`
|
||
- `d1.database_name`
|
||
- `worker.script_name`
|
||
- `pages.project_name`
|
||
- `pages.custom_domain`
|
||
|
||
说明:
|
||
|
||
- 只有 Cloudflare 能读到的字段才会写入
|
||
- `ADMIN_PASSWORDS`、`JWT_SECRET` 之类的值无法从 Cloudflare 反读
|
||
- 如果候选资源不唯一,命令会跳过,不会乱猜
|
||
|
||
## 多账号配置
|
||
|
||
支持在一个 `config.toml` 里定义多个账号或环境,用 `profiles.<name>` 区分。
|
||
|
||
示例:
|
||
|
||
```toml
|
||
[profiles.account_a.cloudflare]
|
||
account_id = "acc-a"
|
||
api_token_env = "CF_API_TOKEN_A"
|
||
zone_name = "example.com"
|
||
|
||
[profiles.account_a.mail]
|
||
domains = ["mail.example.com", "mail2.example.com"]
|
||
|
||
[profiles.account_a.pages]
|
||
custom_domain = "email.example.com"
|
||
|
||
[profiles.account_b.cloudflare]
|
||
account_id = "acc-b"
|
||
api_token_env = "CF_API_TOKEN_B"
|
||
zone_name = "kotei.asia"
|
||
|
||
[profiles.account_b.mail]
|
||
domains = ["mail.kotei.asia", "maila.kotei.asia"]
|
||
|
||
[profiles.account_b.pages]
|
||
custom_domain = "email.kotei.asia"
|
||
```
|
||
|
||
执行时通过 `--profile` 选择:
|
||
|
||
```bash
|
||
uv run cf-temp-email deploy --config config.toml --profile account_a
|
||
uv run cf-temp-email deploy --config config.toml --profile account_b
|
||
```
|
||
|
||
行为说明:
|
||
|
||
- CLI 覆写会写入对应的 `profiles.<name>.*`
|
||
- 每个 profile 使用独立状态文件:
|
||
`.deploy/profiles/<profile>/state.toml`
|
||
- 默认 clone 模式下,每个 profile 也会使用独立工作目录
|
||
|
||
## 域名模型
|
||
|
||
这套工具把“邮箱域名”和“前端域名”分开管理。
|
||
|
||
### 1. 邮箱域名
|
||
|
||
来自 `mail.domains`,支持多个域名,也支持二级域名。
|
||
|
||
例如:
|
||
|
||
```toml
|
||
[mail]
|
||
domains = ["kotei.us.ci", "mail.kotei.us.ci"]
|
||
```
|
||
|
||
这表示系统会同时处理:
|
||
|
||
- `@kotei.us.ci`
|
||
- `@mail.kotei.us.ci`
|
||
|
||
### 2. 前端域名
|
||
|
||
来自 `pages.custom_domain`,当前一次部署只管理一个前端域名。
|
||
|
||
例如:
|
||
|
||
```toml
|
||
[pages]
|
||
custom_domain = "temp-mail.kotei.us.ci"
|
||
```
|
||
|
||
### 3. 约束
|
||
|
||
- `mail.domains` 可以是多个
|
||
- `pages.custom_domain` 当前是单个
|
||
- `pages.custom_domain` 不能和 `mail.domains` 中的任意一个重复
|
||
|
||
原因是:
|
||
|
||
- `mail.domains` 需要承载 Email Routing 的 `MX/TXT`
|
||
- `pages.custom_domain` 需要承载 Pages 的 `CNAME`
|
||
|
||
同一个主机名不能同时做这两件事。
|
||
|
||
## 配置要点
|
||
|
||
### `cloudflare`
|
||
|
||
至少需要:
|
||
|
||
- `zone_name`
|
||
- `api_token` 或 `api_token_env`
|
||
|
||
更推荐使用环境变量:
|
||
|
||
```toml
|
||
[cloudflare]
|
||
api_token_env = "CF_API_TOKEN_KOTEI"
|
||
zone_name = "kotei.us.ci"
|
||
```
|
||
|
||
### `mail.verified_destination_address`
|
||
|
||
现在是可选项。
|
||
|
||
行为如下:
|
||
|
||
- 有值:部署时会校验该地址是否已在 Cloudflare 侧可用
|
||
- 空值:跳过目标地址校验,仍继续配置 `MX/TXT` 和 Catch-all Worker
|
||
|
||
例如:
|
||
|
||
```toml
|
||
[mail]
|
||
verified_destination_address = ""
|
||
```
|
||
|
||
### `worker.vars.ADMIN_PASSWORDS`
|
||
|
||
这是必填项。部署时会使用第一个值请求:
|
||
|
||
```text
|
||
https://<worker.custom_domain>/admin/*
|
||
```
|
||
|
||
用于同步:
|
||
|
||
- 用户注册开关
|
||
- 登录配置
|
||
- 其他管理员接口设置
|
||
|
||
例如:
|
||
|
||
```toml
|
||
[worker.vars]
|
||
ADMIN_PASSWORDS = ["your-strong-password"]
|
||
```
|
||
|
||
### `worker.secrets.JWT_SECRET`
|
||
|
||
可以留空。首次部署前如果为空,脚本会自动生成并写回配置文件。
|
||
|
||
### `linuxdo`
|
||
|
||
如果不用 Linux.do,保持:
|
||
|
||
```toml
|
||
[linuxdo]
|
||
linuxdo_oauth = false
|
||
```
|
||
|
||
只有在 `linuxdo_oauth = true` 时,才需要填写:
|
||
|
||
- `client_id`
|
||
- `client_secret`
|
||
|
||
## CLI 覆写
|
||
|
||
支持显式参数覆写:
|
||
|
||
```bash
|
||
uv run cf-temp-email deploy \
|
||
--config config.toml \
|
||
--profile kotei \
|
||
--api-token "$CF_API_TOKEN_KOTEI" \
|
||
--zone-name "kotei.us.ci" \
|
||
--pages-domain "temp-mail.kotei.us.ci" \
|
||
--worker-name "cloudflare_temp_email"
|
||
```
|
||
|
||
也支持通用 `--set`:
|
||
|
||
```bash
|
||
uv run cf-temp-email deploy \
|
||
--config config.toml \
|
||
--profile kotei \
|
||
--set worker.vars.ADMIN_PASSWORDS='["abc.123"]'
|
||
```
|
||
|
||
说明:
|
||
|
||
- CLI 覆写会先写回 `config.toml`
|
||
- 然后脚本会重新读取配置并执行
|
||
|
||
## 部署阶段
|
||
|
||
部署顺序如下:
|
||
|
||
1. 检查本地工具与 Cloudflare 授权
|
||
2. 准备源码目录
|
||
3. 创建或复用 Pages 项目
|
||
4. 配置 Pages CNAME
|
||
5. 创建或复用 D1,并执行迁移
|
||
6. 生成 `worker/wrangler.toml` 并发布 Worker
|
||
7. 同步管理员接口配置
|
||
8. 配置 Email Routing DNS 与 Catch-all Worker
|
||
9. 构建并发布 Pages
|
||
10. 执行验收检查
|
||
|
||
运行状态会写入:
|
||
|
||
```text
|
||
.deploy/state.toml
|
||
```
|
||
|
||
如果使用 profile,则写入:
|
||
|
||
```text
|
||
.deploy/profiles/<profile>/state.toml
|
||
```
|
||
|
||
## Cloudflare Token 权限
|
||
|
||
最小部署权限建议包括:
|
||
|
||
1. `Cloudflare Pages: Edit`
|
||
2. `D1: Edit`
|
||
3. `Workers Scripts: Write`
|
||
4. `DNS: Write`
|
||
5. `Email Routing Rules: Edit`
|
||
|
||
如果你要使用 `discover-config`,再补这些读取权限:
|
||
|
||
1. `Zone: Read`
|
||
2. `DNS: Read`
|
||
3. `Cloudflare Pages: Read`
|
||
4. `Workers Scripts: Read`
|
||
5. `D1: Read`
|
||
6. `Email Routing Addresses: Read`
|
||
7. `Email Routing Rules: Read`
|
||
|
||
资源范围建议只限定到目标账户和目标 Zone。
|
||
|
||
## 常见问题
|
||
|
||
### 1. 多个邮箱域名是否需要多个 Pages?
|
||
|
||
不需要。
|
||
|
||
通常一个 Pages 前端域名就够了,例如:
|
||
|
||
```toml
|
||
[mail]
|
||
domains = ["kotei.us.ci", "mail.kotei.us.ci"]
|
||
|
||
[pages]
|
||
custom_domain = "temp-mail.kotei.us.ci"
|
||
```
|
||
|
||
### 2. Catch-all 已经指向 Worker,为什么还会提到 destination address?
|
||
|
||
当前版本中,`verified_destination_address` 已经是可选项。留空时不会阻塞部署。
|
||
|
||
### 3. 旧的 `cf_temp_email_deploy.py` 还能用吗?
|
||
|
||
不能。当前统一入口是:
|
||
|
||
```bash
|
||
uv run cf-temp-email ...
|
||
```
|
||
|
||
## 建议流程
|
||
|
||
如果你是接管一个现有站点,推荐按这个顺序:
|
||
|
||
1. `discover-config`
|
||
2. 手动补 `ADMIN_PASSWORDS`
|
||
3. 检查 `mail.domains`、`pages.custom_domain`、`worker.custom_domain`
|
||
4. 运行 `check`
|
||
5. 再运行 `deploy`
|