feat: rebuild email platform and operations console
This commit is contained in:
@@ -1,95 +1,137 @@
|
||||
# Email Unlimit - 轻量级、可自托管的临时邮件解决方案
|
||||
# Email Unlimited
|
||||
|
||||
本项目是一个轻量级的、可自托管的临时邮件解决方案。它允许您使用自己的域名接收邮件,并通过一个简洁的网页界面来查看这些邮件。
|
||||
Email Unlimited 是一个可自托管的临时邮箱服务,包含 Rust API/SMTP 服务、Vue 用户端和 React 管理后台。
|
||||
|
||||
与 `Mailu` 等复杂的邮件套件不同,本项目采用了一个极简的 Node.js 服务来直接接收和处理邮件,部署和维护都非常简单。
|
||||
## 技术栈
|
||||
|
||||
**在线体验:** <a href="https://mail.shenjianl.cn" target="_blank">https://mail.shenjianl.cn</a>
|
||||
- 后端:Rust、Axum、SeaORM、Tokio
|
||||
- 用户端:Vue 3、Pinia、Vue Router、Element Plus
|
||||
- 管理端:React 19、TypeScript、Vite、TanStack Query、shadcn/ui
|
||||
- 数据:MySQL / PostgreSQL / SQLite、Redis
|
||||
- 部署:Docker Compose、Nginx
|
||||
|
||||
**网站截图**:
|
||||

|
||||
服务直接监听 SMTP 端口接收邮件,支持临时邮箱、WebSocket 推送、积分与每日额度、黑名单、灰名单、隔离区、正文 AES-GCM 加密和管理员接口。
|
||||
|
||||
## 技术架构
|
||||
## 本地开发
|
||||
|
||||
* **前端 (Frontend)**: 使用 Vue.js 构建的单页面应用,负责展示收到的邮件列表。
|
||||
* **后端 (Backend)**:
|
||||
* 使用 Node.js 和 Express 搭建的 API 服务器。
|
||||
* 内置一个轻量级的 SMTP 服务器 (`smtp-server`),用于直接接收邮件,无需外部邮件服务。
|
||||
* 通过 WebSocket 实现新邮件的实时推送。
|
||||
* **数据库 (Database)**: 使用 MySQL 存储邮件信息,确保数据的安全性和持久性。
|
||||
* **部署 (Deployment)**: 使用 Docker Compose 统一管理后端服务、数据库和 Nginx,实现一键部署。
|
||||
后端默认使用 `server/config/development.toml`:
|
||||
|
||||
## 前置条件
|
||||
|
||||
在开始之前,请确保您已满足以下条件:
|
||||
|
||||
### 1. 硬件与域名
|
||||
- 一台拥有公网 IP 的云服务器。
|
||||
- 一个您自己的域名(建议已完成备案)。
|
||||
|
||||
### 2. 软件环境
|
||||
- 服务器上已安装 [Docker 和 Docker Compose](https://docs.docker.com/get-docker/)。
|
||||
- 本地开发环境已安装 [Node.js](https://nodejs.org/) (仅用于构建前端)。
|
||||
|
||||
### 3. 域名 DNS 配置
|
||||
要让邮件能正确发送到您的服务器,您必须配置域名的 `A` 记录和 `MX` 记录。假设您的域名是 `example.com`,您希望用于收信的子域名是 `mail.example.com`。
|
||||
|
||||
| 类型 | 主机记录/名称 | 记录值/指向 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| A | mail | `您的服务器公网 IP` | 将 `mail` 子域名指向您的服务器 |
|
||||
| MX | @ | `mail.example.com` | 优先级设置为 10 |
|
||||
|
||||
> **注意**: DNS 记录生效可能需要几分钟到几小时。
|
||||
|
||||
### 4. 申请 SSL/TLS 证书
|
||||
为了启用 HTTPS,您需要为您的域名 `mail.example.com` 申请 SSL 证书。您可以从 Let's Encrypt、阿里云、腾讯云等证书颁发机构免费获取。
|
||||
|
||||
## 部署步骤
|
||||
|
||||
本部署方案使用 Docker Compose 统一管理所有服务(Nginx, Backend, MySQL),实现一键启动,无需在宿主机上安装 Nginx 或其他依赖。
|
||||
|
||||
### 步骤 1: 获取并准备项目
|
||||
将项目代码下载并解压到您的服务器,例如 `/data/email-unlimit` 目录。
|
||||
|
||||
### 步骤 2: 上传 SSL 证书
|
||||
将您申请到的 SSL 证书文件(通常是 `.pem`/.`crt` 和 `.key` 文件)上传到项目的 `certs` 目录下 (`/data/email-unlimit/certs`)。
|
||||
|
||||
### 步骤 3: 构建前端静态文件 (本地环境)
|
||||
1. 在您的**本地开发机**上,进入 `frontend` 目录,修改 `.env` 环境变量文件:
|
||||
```env
|
||||
VITE_APP_DOMAIN=example.com # 改为你的主域名
|
||||
```
|
||||
2. 安装依赖并构建:
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
3. 将构建生成的 `dist` 目录(位于 `frontend/dist`)**完整上传**到服务器的 `/data/email-unlimit/frontend` 目录下。
|
||||
|
||||
### 步骤 4: 修改 Nginx 配置 (服务器)
|
||||
编辑项目根目录下的 `nginx.full.conf` 文件,仅需修改以下三项:
|
||||
```nginx
|
||||
server_name mail.example.com; # 改为您自己的域名
|
||||
ssl_certificate /etc/nginx/certs/your_certificate.pem; # 改为您自己的证书文件名
|
||||
ssl_certificate_key /etc/nginx/certs/your_certificate.key; # 改为您自己的密钥文件名
|
||||
```powershell
|
||||
cd server
|
||||
cargo run
|
||||
```
|
||||
> **注意**: 配置文件中的证书路径 `/etc/nginx/certs/` 是容器内的路径,它会映射到宿主机的 `/data/email-unlimit/certs` 目录,请确保文件名正确。
|
||||
|
||||
### 步骤 5: 启动服务 (服务器)
|
||||
在服务器的项目根目录 (`/data/email-unlimit`) 下执行以下命令:
|
||||
```bash
|
||||
# -f 指定使用 docker-compose.full.yml 配置文件,-d 表示后台运行
|
||||
docker compose -f docker-compose.full.yml up -d
|
||||
用户端和管理端均使用 pnpm:
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm dev
|
||||
|
||||
cd admin
|
||||
pnpm install
|
||||
pnpm dev
|
||||
```
|
||||
服务启动后,您可以通过 `docker compose -f docker-compose.full.yml logs -f` 查看实时日志。
|
||||
|
||||
## 如何使用
|
||||
两个前端在开发模式下都通过 Vite 代理访问 `http://127.0.0.1:3000`。需要连接其他 API 时,可分别设置 `VITE_API_PROXY_TARGET`;生产构建连接独立 API 时使用:
|
||||
|
||||
1. **访问您的网站**: 在浏览器中打开 `https://mail.example.com` (替换为您的域名)。
|
||||
2. **发送测试邮件**: 使用任何邮箱客户端,向 `anything@example.com` (例如 `test@example.com`) 发送一封邮件。
|
||||
3. **查看邮件**: 在网站首页的输入框中输入您刚刚使用的收件人地址 (`test@example.com`),点击查询,即可看到收到的邮件。
|
||||
```env
|
||||
VITE_API_BASE_URL=http://localhost:3000
|
||||
```
|
||||
|
||||
## Docker 部署
|
||||
|
||||
开发/内网部署:
|
||||
|
||||
先修改 `compose.env` 中所有 `CHANGE_ME` 配置,然后运行:
|
||||
|
||||
```powershell
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
用户端地址为 `http://localhost:8080`,管理端地址为 `http://localhost:8081`,API 地址为 `http://localhost:3000`,SMTP 监听宿主机 `25` 端口。
|
||||
|
||||
HTTPS 完整部署:
|
||||
|
||||
1. 修改 `compose.full.env` 中所有 `CHANGE_ME` 配置。
|
||||
2. 修改 `nginx.full.conf` 中的域名与证书文件名。
|
||||
3. 将证书放入 `certs/`。
|
||||
4. 启动服务。
|
||||
|
||||
```powershell
|
||||
docker compose -f docker-compose.full.yml up -d --build
|
||||
```
|
||||
|
||||
使用外部数据库时,复制 `compose.self.env.example` 为 `compose.self.env`,填写数据库连接后运行:
|
||||
|
||||
```powershell
|
||||
docker compose -f docker-compose.self.yml up -d --build
|
||||
```
|
||||
|
||||
生产环境会拒绝默认 JWT 密钥、通配 CORS,以及缺失或占位的 32 字节正文加密密钥。
|
||||
|
||||
## 首个管理员
|
||||
|
||||
新部署时,将 `AUTH__BOOTSTRAP_ADMIN_EMAIL` 设置为首个管理员邮箱,并为 `AUTH__INVITE_CODE` 设置至少 16 字符的随机值。服务启动后,用这两个值注册:
|
||||
|
||||
```powershell
|
||||
$body = @{
|
||||
email = "admin@example.com"
|
||||
password = "replace-with-a-strong-password"
|
||||
invite_code = "replace-with-the-configured-invite-code"
|
||||
} | ConvertTo-Json
|
||||
|
||||
Invoke-RestMethod -Method Post `
|
||||
-Uri "http://localhost:3000/auth/register" `
|
||||
-ContentType "application/json" `
|
||||
-Body $body
|
||||
```
|
||||
|
||||
注册成功后即可登录管理端。已有管理员的部署可将 `AUTH__BOOTSTRAP_ADMIN_EMAIL` 留空。
|
||||
|
||||
普通用户通过用户端注册和登录。用户端支持创建/吊销邮箱、收信与 WebSocket 推送、附件下载、邮件删除、积分余额、今日额度与积分流水。每个邮箱使用独立 token;浏览器首次打开已有邮箱时会自动轮换并保存新 token。
|
||||
|
||||
## 积分规则
|
||||
|
||||
积分规则保存在数据库中,不使用 `CREDIT__*` 环境变量。首次启动会写入内置默认值,之后可在管理端的“积分规则”页面修改,保存后从下一次业务操作立即生效并跨容器重启保留。
|
||||
|
||||
| 规则 | 默认值 |
|
||||
| ---- | ------ |
|
||||
| 注册奖励 | 30 积分 |
|
||||
| 每日签到 | 3 积分 |
|
||||
| 奖励余额上限 | 90 积分 |
|
||||
| 创建邮箱 | 2 积分/个 |
|
||||
| 接收邮件 | 1 积分/封 |
|
||||
| 每日邮箱上限 | 3 个 |
|
||||
| 每日收信上限 | 20 封 |
|
||||
|
||||
所有邮箱创建和正常邮件接收从第一次开始扣分,不存在免费次数。删除邮件、吊销邮箱或自然过期不会返还积分和当日次数。隔离邮件在管理员放行时才占用次数并扣分。积分不可购买、转账、兑换或提现。
|
||||
|
||||
## DNS
|
||||
|
||||
用于接收邮件的域名至少需要:
|
||||
|
||||
| 类型 | 名称 | 值 |
|
||||
| ---- | ------ | ------------------ |
|
||||
| A | `mail` | 服务器公网 IP |
|
||||
| MX | `@` | `mail.example.com` |
|
||||
|
||||
公网 SMTP 还需要开放 TCP 25,并根据实际域名调整 `server/config/production.toml` 的 `smtp.hostname` 与 `smtp.local_domains`。
|
||||
|
||||
## 验证
|
||||
|
||||
```powershell
|
||||
cd server
|
||||
cargo test
|
||||
cargo check
|
||||
|
||||
cd ..\frontend
|
||||
pnpm build
|
||||
|
||||
cd ..\admin
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目采用 MIT 许可证。详情请参阅 [LICENSE](LICENSE) 文件。
|
||||
MIT,详见 [LICENSE](LICENSE)。
|
||||
|
||||
Reference in New Issue
Block a user