轻量级临时邮箱收件系统,单个 Docker 容器部署,支持多域名、API 鉴权、临时邮箱生成。
- 两种收件模式:内置 SMTP 服务器 或 Cloudflare Email Worker 转发
- REST API 查询/管理邮件
- 临时邮箱地址生成,支持自定义前缀和过期时间
- 多域名绑定
- API Key 鉴权保护
- SQLite 持久化存储(sql.js,无需额外数据库)
- React + TailwindCSS 前端界面
- 单容器 Docker 部署
- 复制环境变量文件并修改配置:
cp .env.example .env- 编辑
.env文件:
AUTH_KEY=your-secret-key-here
DOMAINS=mail.example.com,tmp.example.org
HTTP_PORT=3000
SMTP_PORT=25
MAIL_MODE=smtp- 启动服务:
docker compose up -d服务启动后:
- Web 界面:
http://localhost:3000 - SMTP 服务:端口
25
无需 Docker,直接在本地运行。服务启动时会自动读取项目根目录的 .env 文件。
# 1. 复制并编辑环境变量
cp .env.example .env
# 编辑 .env 设置 AUTH_KEY、DOMAINS 等
# 2. 安装依赖
npm run install:all
# 3. 构建
npm run build
# 4. 启动
npm start服务启动后:
- Web 界面:
http://localhost:3000 - SMTP 服务:端口
25(smtp 模式下)
# 安装依赖
npm run install:all
# 确保 .env 已配置
# 启动后端(自动读取 .env)
npm run dev:server
# 启动前端(另一个终端)
npm run dev:web| 变量 | 说明 | 默认值 |
|---|---|---|
AUTH_KEY |
API 鉴权密钥(必填) | - |
DOMAINS |
允许接收邮件的域名,逗号分隔 | localhost |
HTTP_PORT |
HTTP 服务端口 | 3000 |
SMTP_PORT |
SMTP 服务端口(仅 smtp 模式) | 25 |
DATA_DIR |
数据存储目录 | ./data |
MAIL_MODE |
收件模式:smtp 或 cf-worker |
smtp |
Tiny Mail 支持两种收件模式,通过 MAIL_MODE 环境变量切换。
内置 SMTP 服务器直接接收邮件。需要服务器 25 端口对外开放。
MAIL_MODE=smtp
SMTP_PORT=25适用于:有独立服务器、25 端口未被封禁的场景。
通过 Cloudflare Email Routing + Worker 转发邮件到 Tiny Mail 的 HTTP 接口。不需要开放 25 端口,适合大多数云服务器。
MAIL_MODE=cf-worker配置步骤:
- 登录 Cloudflare Dashboard
- 选择你的域名 → 左侧菜单点击 Email → Email Routing
- 点击 Get started,按提示完成启用(Cloudflare 会自动添加所需的 MX 和 TXT 记录)
方式 A:通过命令行部署(推荐)
cd worker
npm install
# 修改 wrangler.toml 中的 TINY_MAIL_URL 为你的 Tiny Mail 服务地址
# 例如:TINY_MAIL_URL = "https://tiny-mail.example.com"
# 设置密钥(与 .env 中的 AUTH_KEY 一致)
npx wrangler secret put AUTH_KEY
# 部署到 Cloudflare
npm run deploy方式 B:通过 Cloudflare 控制台手动创建
如果不想在本地安装 wrangler,可以直接在 Cloudflare 后台操作:
- 进入 Cloudflare Dashboard → Workers & Pages → Create
- 选择 Create Worker,命名为
tiny-mail-worker,点击 Deploy 先创建一个空 Worker - 进入刚创建的 Worker → Settings → Variables and Secrets:
- 添加变量
TINY_MAIL_URL,值为你的 Tiny Mail 服务地址(如https://tiny-mail.example.com) - 添加密钥
AUTH_KEY,值与.env中的AUTH_KEY一致(点击 Encrypt 加密存储)
- 添加变量
- 进入 Worker → Edit Code,将编辑器中的代码替换为以下内容:
export default {
async email(message, env, ctx) {
const to = message.to;
const url = `${env.TINY_MAIL_URL}/api/incoming?to=${encodeURIComponent(to)}`;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"Authorization": `Bearer ${env.AUTH_KEY}`,
},
body: await new Response(message.raw).arrayBuffer(),
});
if (!response.ok) {
const text = await response.text();
console.log(`Failed to deliver mail to ${to}: ${response.status} ${text}`);
message.setReject(`Failed to process email: ${response.status}`);
} else {
console.log(`Mail delivered to ${to}`);
}
},
};- 点击 Deploy 保存并部署
- 进入 Cloudflare Dashboard → 你的域名 → Email → Email Routing → Routing rules
- 配置方式(二选一):
- Catch-all(接收所有邮件):在 Catch-all address 行点击 Edit,Action 选择 Send to a Worker,选择
tiny-mail-worker - 指定地址:点击 Create address,填写自定义地址,Action 选择 Send to a Worker,选择
tiny-mail-worker
- Catch-all(接收所有邮件):在 Catch-all address 行点击 Edit,Action 选择 Send to a Worker,选择
- 确保
.env中DOMAINS包含你在 Cloudflare 配置的域名 - 发送一封测试邮件到配置的地址,在 Tiny Mail 前端查看是否收到
- 如果未收到,可在 Cloudflare Dashboard → Workers →
tiny-mail-worker→ Logs 中查看错误日志
工作流程:
发件方 → Cloudflare Email Routing → Worker → POST /api/incoming → Tiny Mail 存储
使用 SMTP 模式时,需要自行配置 DNS 让外部邮件服务器能找到你的服务器。
要让外部邮件(如 Gmail、QQ 邮箱)能发送到你的临时邮箱,需要正确配置 DNS 记录。邮件投递依赖 MX(Mail Exchange)记录,发件方会查询收件域名的 MX 记录来确定邮件该投递到哪台服务器。
想让 [email protected] 能收到邮件:
DNS 记录:
| 类型 | 主机记录 | 记录值 | 说明 |
|---|---|---|---|
| A | 1.2.3.4 |
指向你运行 Tiny Mail 的服务器 IP | |
| MX | @ | mail.example.com |
告诉发件方:发往 example.com 的邮件投递到 mail.example.com |
MX 记录的优先级填
10(数字越小优先级越高,单台服务器随意填即可)。
.env 配置:
DOMAINS=example.com效果: 任何人发邮件到 [email protected],Tiny Mail 都会接收。
想让 [email protected] 能收到邮件(不影响主域名的邮件服务):
DNS 记录:
| 类型 | 主机记录 | 记录值 | 说明 |
|---|---|---|---|
| A | 1.2.3.4 |
指向你的服务器 IP | |
| MX | mail.example.com |
发往 mail.example.com 的邮件投递到自身 |
.env 配置:
DOMAINS=mail.example.com同时用 example.com 和 tmp.example.org 收件:
DNS 记录(example.com):
| 类型 | 主机记录 | 记录值 |
|---|---|---|
| A | 1.2.3.4 |
|
| MX | @ | mail.example.com |
DNS 记录(example.org):
| 类型 | 主机记录 | 记录值 |
|---|---|---|
| MX | tmp | mail.example.com |
多个域名的 MX 可以指向同一台服务器。
.env 配置:
DOMAINS=example.com,tmp.example.orgDNS 记录生效后(通常几分钟到 48 小时),可以用以下命令验证:
# 查询 MX 记录
dig MX example.com
# 或
nslookup -type=mx example.com
# 测试 SMTP 连通性
telnet mail.example.com 25- 服务器的 25 端口必须对外开放(部分云服务商默认封禁 25 端口,需要申请解封或使用其他端口)
- 如果使用非标准端口(如 2525),外部邮件服务器无法投递(MX 标准只支持 25 端口),仅适合内部测试
- 建议同时配置 SPF 记录(虽然 Tiny Mail 只收不发,但有助于减少被误判为垃圾邮件源):
example.com. TXT "v=spf1 mx -all"
使用 Cloudflare Worker 模式时,DNS 由 Cloudflare 管理,无需手动配置 MX 记录。
Cloudflare 启用 Email Routing 后会自动添加所需的 MX 和 TXT 记录。你只需要:
- 域名的 DNS 托管在 Cloudflare
- 在 Cloudflare Dashboard 中启用 Email Routing(会自动配置 MX 记录)
- 配置路由规则将邮件转发到 Worker
- 后端: Node.js + TypeScript + Express + smtp-server
- 存储: SQLite (sql.js)
- 前端: React 18 + TailwindCSS 3 + Vite
- 部署: Docker
tiny-mail/
├── server/ # 后端服务
│ └── src/
│ ├── index.ts # 入口
│ ├── config.ts # 配置管理
│ ├── smtp.ts # SMTP 服务器
│ ├── api.ts # REST API 路由
│ ├── store.ts # SQLite 数据层
│ └── types.ts # 类型定义
├── web/ # 前端
│ └── src/
│ ├── App.tsx # 主组件
│ ├── api.ts # API 调用
│ └── components/ # UI 组件
├── worker/ # Cloudflare Email Worker
│ ├── src/index.ts # Worker 入口
│ ├── wrangler.toml # Wrangler 配置
│ └── package.json
├── .env.example # 环境变量模板
├── Dockerfile
├── docker-compose.yml
└── API.md # 接口文档
MIT