主题
Mailsyra
专为多邮箱用户打造的自托管邮件客户端
项目简介
Mailsyra 是一款基于 FlyMail(飞邮) 二次开发的自托管邮件客户端, 让用户在一个界面统一管理腾讯邮箱、网易邮箱、iCloud、新浪邮箱以及自定义 IMAP/SMTP 邮箱。邮件缓存与配置存储在用户自己的服务器上,隐私可控。



核心功能
- 多邮箱聚合:所有邮箱邮件混排展示,按时间统一排序,支持按邮箱筛选与身份标识
- 邮件收发:支持纯文本 / HTML 富文本编辑、附件上传下载、草稿保存、定时发送
- 实时同步:IMAP IDLE 长连接秒级推送新邮件,Poll 轮询兜底兼容更多平台
- 智能缓存:MySQL 摘要缓存 + 增量同步,收件箱秒开,断网仍可浏览已缓存邮件
- 本地备份:邮件以
.eml格式归档到管理员允许的服务器目录,支持附件完整保存与独立下载 - 桌面通知:WebSocket 实时推送新邮件通知,通知中心统一管理
- 移动端适配:响应式布局,手机端触控友好
支持的邮箱平台
| 邮箱平台 | 认证方式 | 实时同步 | 发送邮件 |
|---|---|---|---|
| QQ 邮箱 | 授权码 | IDLE | SMTP |
| 网易邮箱 (163/126/yeah.net) | 授权码 | Poll | SMTP |
| iCloud | 应用专用密码 | Poll | SMTP |
| 新浪邮箱 | 授权码 | Poll | SMTP |
| 自定义 IMAP/SMTP | 账号密码 | Poll | SMTP |
技术栈
| 层级 | 技术 |
|---|---|
| 前端 | Vue 3 + TypeScript + Pinia + Vite |
| 后端 | Python 3.11 + FastAPI + PyMySQL |
| 数据库 | MySQL 5.7 |
| 邮件协议 | IMAP (IDLE/Poll) + SMTP |
| 实时通信 | WebSocket |
| 构建工具 | Nuitka (二进制编译) + fnpack |
目录结构
text
Mailsyra/
├── frontend/ # Vue 前端:package.json、vite.config.ts、Dockerfile
├── backend/ # FastAPI 后端:.env、requirements.txt、Dockerfile
├── docker-compose.yaml # 一键编排:MySQL + 后端 + 前端
├── dev.sh # 本地前后端统一启动、停止与状态检查
├── docs/
└── README.md一、本地运行(开发模式)
本地运行需要手动准备 MySQL 5.7。前端(Vite dev server,端口 5173)和后端(FastAPI,端口 8080)各自独立启动,通过 Vite 的 /api、/ws 反向代理连到后端。
1. 运行环境
- Python 3.11 或更高版本
- Node.js 18 或更高版本,以及 npm
- MySQL 5.7(本地或局域网内的实例均可)
2. 准备后端配置
bash
cp backend/.env.example backend/.envbackend/.env 关键配置(本地运行时 MAILSYRA_DB_HOST 用 127.0.0.1,容器运行时改成 mysql):
dotenv
# 服务端配置
MAILSYRA_PORT=8080
MAILSYRA_DATA_DIR=data
MAILSYRA_COOKIE_SECURE=0
# MySQL 连接
MAILSYRA_DB_HOST=127.0.0.1
MAILSYRA_DB_PORT=3306
MAILSYRA_DB_USER=root
MYSQL_ROOT_PASSWORD=你的MySQL root密码
MAILSYRA_DB_NAME=mailsyra3. 创建数据库
先在本地 MySQL 中创建 mailsyra 数据库(utf8mb4 字符集):
sql
CREATE DATABASE mailsyra CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;数据表由后端在首次启动时自动创建,无需手动导入表结构。
4. 安装依赖
bash
# 后端
python3 -m pip install -r backend/requirements.txt
# 前端(首次启动时会自动安装;这里手动安装也行)
cd frontend && npm install --legacy-peer-deps5. 启动服务(二选一)
方式 A:一键脚本启动(推荐)
在项目根目录执行:
bash
./dev.sh start脚本会先停止占用 5173、8080 端口的旧进程,再分别拉起前后端。按 Ctrl+C 可停止本次启动的服务。
辅助命令:
bash
./dev.sh status # 查看前后端运行状态
./dev.sh restart # 重启
./dev.sh stop # 停止
./dev.sh --help # 查看所有支持的命令方式 B:手动分别启动
打开两个终端窗口:
bash
# 终端 1:启动后端
bash backend/scripts/start-backend.sh
# 终端 2:启动前端
bash frontend/scripts/start-frontend.sh6. 访问
| 用途 | 地址 |
|---|---|
| Web 页面 | http://localhost:5173/ |
| 后端健康检查 | http://localhost:8080/api/health |
| 后端接口文档 | http://localhost:8080/docs |
前端的
/api/...和/ws/...请求会被 Vite dev server 自动反代到http://localhost:8080,前端代码里写相对路径即可。
7. 首次使用
首次访问 Web 页面时,系统会显示管理员初始化页面。设置用户名和密码后即可登录;用户名为 3–32 位字母、数字、下划线或连字符,密码至少 8 位。登录后可在页面中添加 IMAP/SMTP 邮箱账号。
二、Docker 部署(生产环境)
项目根目录的 docker-compose.yaml 编排了 3 个容器:mysql-5.7.44、backend、frontend。数据库密码唯一在 backend/.env 里维护,部署时只需新建一个工作目录、复制项目文件、生成 .env 即可。
1. 运行环境
- Docker 20.10 或更高版本
- Docker Compose v1.29 或更高版本(也支持新版
docker composeCLI) - 宿主机空闲端口:
3306(MySQL)、8080(后端)、5173(前端)
2. 创建工作目录
bash
mkdir -p /home/application/mailsyra
cd /home/application/mailsyra3. 复制项目文件
将项目源码(backend/、frontend/、docker-compose.yaml、.gitignore 等)拷贝或 clone 到该目录:
bash
# 用 git 拉取代码
git clone <你的仓库地址> .4. 生成配置文件
只需要准备一份 .env(backend/.env),所有密码都在这里:
bash
# 复制后端 .env 模板
cp backend/.env.example backend/.env编辑 backend/.env,把 MYSQL_ROOT_PASSWORD 改成你的强密码(其余配置保持默认即可):
dotenv
MAILSYRA_PORT=8080
MAILSYRA_DATA_DIR=data
MAILSYRA_COOKIE_SECURE=0
# 容器内通过服务名访问 MySQL
MAILSYRA_DB_HOST=mysql
MAILSYRA_DB_PORT=3306
MAILSYRA_DB_USER=root
MYSQL_ROOT_PASSWORD=你的强密码
MAILSYRA_DB_NAME=mailsyra容器化部署时
MAILSYRA_DB_HOST必须是mysql(docker-compose 服务名),不能是127.0.0.1。 后端代码与 MySQL 镜像都通过env_file: ./backend/.env注入MYSQL_ROOT_PASSWORD,整份docker-compose.yaml没有任何明文密码。
5. 创建数据目录
为避免 docker-compose 首次启动时把数据目录自动创建为 root 权限,提前建好:
bash
mkdir -p mysql-data backend-data这两个目录分别用于 MySQL 数据持久化和后端运行数据(邮件 .eml 备份、日志、缓存)持久化。后续 docker compose up 会自动挂载到容器内。
6. 构建并启动/直接启动
bash
docker compose up -d --build
或者 直接 docker compose up -d7. 验证
bash
# 查看容器状态
docker compose ps
# 实时查看日志
docker compose logs -f
# 健康检查
curl http://localhost:8080/api/health启动后可访问:
| 用途 | 地址 |
|---|---|
| Web 页面 | http://localhost:5173/ |
| 后端健康检查 | http://localhost:8080/api/health |
| 后端接口文档 | http://localhost:8080/docs |
| MySQL | localhost:3306(账号 root / 密码同 MYSQL_ROOT_PASSWORD) |
8. 数据持久化
| 宿主机目录 | 容器内挂载点 | 用途 |
|---|---|---|
./mysql-data | /var/lib/mysql | MySQL 数据文件;删掉会丢邮件缓存与同步状态 |
./backend-data | /app/data | 后端日志、邮件 .eml 备份、附件目录等 |
9. 常用命令
bash
# 停止服务(保留数据卷)
docker compose down
# 停止并删除 MySQL 数据卷(会清空所有邮件缓存,慎用)
docker compose down -v
# 重新构建镜像(修改了 Dockerfile 或依赖后使用)
docker compose build
# 重新构建并启动
docker compose up -d --build
# 查看后端实时日志
docker compose logs -f backend
# 进入后端容器排查问题
docker compose exec backend bash
# 进入 MySQL 容器执行 SQL
docker compose exec mysql mysql -u root -p"$MYSQL_ROOT_PASSWORD"三、上 HTTPS(可选)
本地开发默认是 HTTP。如果生产环境要上 HTTPS,推荐在宿主机上用 Nginx 反向代理,而不是在容器里改证书。
示例 Nginx 片段(/etc/nginx/conf.d/mailsyra.conf):
nginx
server {
listen 80;
server_name mail.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name mail.example.com;
ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;
# 前端
location / {
proxy_pass http://127.0.0.1:5173;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 后端 API + WebSocket
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /ws/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}反代之后还需要把 backend/.env 的 MAILSYRA_COOKIE_SECURE 改成 1,让浏览器只在 HTTPS 下发送登录 cookie。
开源协议
本项目基于 GPL-3.0 协议开源。
本项目是依据 GPL-3.0 继续开发的独立派生版本。原始版权与修改说明见 NOTICE。
再次感谢🙏 原作者的支持,没有 FlyMail 就没有 Mailsyra。
任何人都可以在 GPL-3.0 条款下使用、修改和分发本项目;派生作品必须继续遵守该许可证并保留必要的版权声明。
让邮件服务保持简单、可靠、可控
