81 lines
5.2 KiB
Markdown
81 lines
5.2 KiB
Markdown
# 反馈邮件服务:1Panel 部署说明
|
||
|
||
如果80/443由雷池WAF占用,且OpenResty为host模式、端口10080/12443,请优先使用[雷池专用部署指南](deployment-safeline-1panel.md)和`openresty-safeline-http.conf.example`,HTTPS在雷池处理。
|
||
|
||
已准备好服务文件,尚未连接服务器、部署或发送真实邮件。
|
||
|
||
| 项目 | 配置 |
|
||
|---|---|
|
||
| 服务器 | Ubuntu / 1Panel,公网 IP `43.138.57.216` |
|
||
| 域名 | `app.glowtps.cn` |
|
||
| App 提交地址 | `https://app.glowtps.cn/v1/feedback` |
|
||
| 飞书发件邮箱 | `authors@glowtps.cn` |
|
||
| 固定收件邮箱 | `tps-david@glowtps.cn` |
|
||
| 发信服务器 | `smtp.feishu.cn`,端口 `465`,SSL |
|
||
|
||
## 1. 上传服务文件
|
||
|
||
在 1Panel 文件管理中,准备 `/opt/app-feedback` 目录,把本目录的服务文件上传进去。需要保留 `feedback_service.py`、`main.py`、`requirements.txt`、`Dockerfile`、`docker-compose.yml`、`.dockerignore`、`.env.example` 和 `reverse-proxy.conf.example`。
|
||
|
||
不要上传开发电脑上的 `.deps`、`.venv`、`.test*`、缓存目录、数据库或已有的 `.env`。这些文件不属于部署包。
|
||
|
||
## 2. 在服务器填写 `.env`
|
||
|
||
将 `.env.example` 复制为 `.env`,确认以下公开配置:
|
||
|
||
```dotenv
|
||
SMTP_HOST=smtp.feishu.cn
|
||
SMTP_PORT=465
|
||
SMTP_TLS=ssl
|
||
SMTP_USERNAME=authors@glowtps.cn
|
||
MAIL_FROM=authors@glowtps.cn
|
||
MAIL_TO=tps-david@glowtps.cn
|
||
DATABASE_PATH=/app/data/feedback.sqlite3
|
||
```
|
||
|
||
另外填写两个服务器专用秘密:
|
||
|
||
- `SMTP_PASSWORD`:在飞书邮箱启用第三方邮件客户端访问后取得的客户端授权密码。仅在服务器 `.env` 中填写,不要写进 App、APK 或源代码,也不要发到聊天中。
|
||
- `IDEMPOTENCY_SECRET`:用于保护重复提交记录的随机密钥,至少 32 字节。可在服务器终端执行 `openssl rand -hex 32` 生成,再填入 `.env`。后续更新服务时保留这个值。
|
||
|
||
两个示例占位值必须替换。建议用英文单引号包住秘密值,避免其中的 `$` 被 Compose 替换。通过文件管理或 `chmod 600 .env` 限制 `.env` 的读取权限。其余限制参数可以保留默认值。
|
||
|
||
## 3. 启动 Compose
|
||
|
||
在 1Panel 的服务器终端进入上传目录并启动:
|
||
|
||
```sh
|
||
cd /opt/app-feedback
|
||
docker compose up -d --build
|
||
docker compose ps
|
||
curl --fail http://127.0.0.1:18080/healthz
|
||
```
|
||
|
||
也可以使用 1Panel 的容器编排入口导入 `docker-compose.yml`;需要确认构建目录是 `/opt/app-feedback`,同一目录内能找到 Dockerfile、服务文件和 `.env`。
|
||
|
||
`healthz` 正常时会返回 `{"status":"ok"}`。它不会发送邮件,也不代表飞书密码已经验证。如果启动失败,在 1Panel 查看容器日志。不要公开分享 `.env`、完整容器详情或 `docker compose config` 输出,这些内容可能包含密码。
|
||
|
||
## 4. 配置域名、HTTPS 和反向代理
|
||
|
||
1. 在域名 DNS 中,将 `app.glowtps.cn` 的 A 记录指向 `43.138.57.216`。
|
||
2. 在腾讯云安全组中允许网站所需的 80、443 端口;`18080` 保持对公网关闭。
|
||
3. 在 1Panel 配置 `app.glowtps.cn` 网站,申请或选择 HTTPS 证书,启用 HTTPS 跳转。
|
||
4. 设置反向代理到 `http://127.0.0.1:18080`,并参考 `reverse-proxy.conf.example` 加入反馈接口和健康检查的配置。保留 1Panel 生成的证书设置;如果域名已有网站,只增加对应接口,保留其他页面和路由。
|
||
5. 通过 1Panel 检查配置后再重新加载 OpenResty,访问 `https://app.glowtps.cn/healthz` 验证。
|
||
|
||
**网络方式需要确认:**上述地址要求 OpenResty 能访问宿主机的 `127.0.0.1`。如果 OpenResty 使用独立的 Docker 桥接网络,它的 `127.0.0.1` 是自己的容器;此时需让 OpenResty 和反馈服务加入同一个私有 Docker 网络,改为代理 `feedback:8000`,并取消宿主机端口发布、调整可信代理设置。不要通过向公网开放 `18080` 来解决连接问题。具体配置见同目录英文 README。
|
||
|
||
## 5. 由操作者进行一次真实邮件验证
|
||
|
||
服务器和证书准备完成后,由操作者从 App 提交一条明确标记为“部署测试”的反馈,确认接口返回 `success:true`、`status:sent`,并在 `tps-david@glowtps.cn` 检查收件。再使用**相同提交 ID 和相同内容**重试一次,确认没有重复邮件。
|
||
|
||
接口成功表示飞书发信服务器已接受邮件;是否进入收件箱仍需检查。若返回“发送状态不确定”,先检查收件和投递记录,不要换一个提交 ID 强行重发。完整错误说明见 README。
|
||
|
||
## 6. 更新时保留数据和秘密
|
||
|
||
服务使用 Compose 的 SQLite 数据卷保存重复提交状态,默认保留七天;文本、联系方式和附件不写入这个数据库。邮件本身按飞书及收件邮箱的策略保存。
|
||
|
||
更新时保留 `.env`、原来的 `IDEMPOTENCY_SECRET` 和 SQLite 数据卷,继续在同一部署目录使用同一个 Compose 项目。需要停服时使用 `docker compose down`,**不要使用 `docker compose down -v`**,后者会删除数据卷并丢失重复提交记录。需要备份时采用一致的 SQLite 备份方式,详细方法见 README。
|
||
|
||
目前还需要在服务器完成:填写飞书客户端授权密码、生成持久密钥、启动容器、检查 DNS/证书/代理网络,并执行一次受控的真实收件验证。
|