Files

81 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 反馈邮件服务: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/证书/代理网络,并执行一次受控的真实收件验证。