# 反馈邮件服务:1Panel 部署说明 已准备好服务文件,尚未连接服务器、部署或发送真实邮件。 | 项目 | 配置 | |---|---| | 服务器 | 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/证书/代理网络,并执行一次受控的真实收件验证。