7.1 KiB
TPSchedule 更新服务
独立于反馈服务,管理员在 https://app.glowtps.cn/update 发布安卓版本;APP查询 https://app.glowtps.cn/v1/updates/android。无需接入第三方推送SDK。APP冷启动进入首页后检查一次,后台无版本或网络失败时安静结束;“我的→检查更新”提供手动查询。有新版时用户可稍后处理,或打开浏览器下载。
Ubuntu、1Panel、雷池部署步骤
已知环境:雷池80/443 → host网络的OpenResty10080 → 原反馈容器18080。新增更新容器仅监听 127.0.0.1:18081;反馈服务、SMTP、域名证书、原路由均不需要修改。本工程没有访问服务器或执行部署。
1. 上传服务文件
把 TPSchedule-update-server.zip 上传到1Panel文件管理器并解压,将 updates 目录内的文件放到 /opt/tpschedule-updates。确认该目录直接包含 Dockerfile、docker-compose.yml、main.py、update_service.py 等文件。
在1Panel终端确认18081没有其他服务占用:
ss -ltn '( sport = :18081 )'
cd /opt/tpschedule-updates
cp .env.example .env
chmod 600 .env
docker compose build
如果18081已占用,选择未使用的本机端口并同时修改Compose与下方OpenResty示例;不要停止其他服务。首次构建需要服务器访问镜像源及Python依赖源。
2. 设置更新后台登录
执行:
docker compose run --rm --no-deps updates python manage.py
按提示输入至少12位后台密码并再次确认。工具会输出 ADMIN_PASSWORD_HASH='…' 和 SESSION_SECRET='…' 两行。只在服务器将这两行填入 .env 的对应位置,保留单引号,避免Docker把密码哈希中的 $ 当作变量。不要把输出或密码发到聊天中。
.env其他项目:
PUBLIC_ORIGIN=https://app.glowtps.cn
ADMIN_USERNAME=admin
DATA_DIR=/app/data
PUBLIC_ORIGIN不加结尾斜杠或路径,必须使用浏览器实际访问的HTTPS域名。可以自行修改ADMIN_USERNAME。密码以scrypt哈希保存;明文密码不写入APP或源码。SESSION_SECRET是更新后台自己的会话密钥,与APK签名密钥和反馈服务密钥无关。日后改密码时可重新运行工具并替换上述两行,重建服务使原登录失效。
3. 启动并检查容器
docker compose up -d
docker compose ps
curl --fail --max-time 10 http://127.0.0.1:18081/healthz
curl --fail --max-time 10 http://127.0.0.1:18081/v1/updates/android
健康检查返回 {"status":"ok"};首次没有发布记录,公开接口返回:
{"schema_version":1,"application_id":"com.tpschedule.app","latest":null}
.env、Compose项目名tpschedule-updates及update-data数据卷要长期保留;正常重建不会清空版本。不要执行带 -v 的删除数据卷命令。服务配置错误时检查 docker compose logs --tail 30 updates,分享错误前不要附带.env或秘密值。
4. 配置现有OpenResty站点
1Panel“网站”→app.glowtps.cn→配置文件,在现有 server { … } 内添加 openresty-safeline.conf.example 中的三个 location。不要把三个location放到已有location内部,不要另建相同域名的server;若已有相同路径请合并替换,不重复定义。
这三个路径转发至 http://127.0.0.1:18081,原 /v1/feedback 仍转发至18080。验证配置并重载OpenResty。无需改变10080/12443监听、雷池回源地址和TLS证书;内部10080站点仍不强制跳转HTTPS。
雷池保持 app.glowtps.cn → 127.0.0.1:10080。如果雷池启用了必须由浏览器完成的人机验证,仅对APP查询路径 /v1/updates/android 关闭交互挑战;保留网站其他保护。此API是公开、只读的版本信息,不能要求管理员登录或返回HTML挑战页面。后台 /update 保持正常防护,登录和发布使用POST,不能缓存这些路径。
浏览器打开 https://app.glowtps.cn/update,应看到蓝色登录页面。后台使用Secure Cookie,必须通过外部HTTPS访问,直接用服务器IP或HTTP测试登录会失败。随后访问公开JSON接口核对转发。
5. 发布版本
先把APK放到你现有的公开HTTPS下载位置,例如腾讯云COS或1Panel站点中已经可以下载的目录。本服务只管理版本信息,不存放APK;后台不会代表你访问下载链接。请用手机浏览器确认链接能打开,无登录要求且能下载正确文件。
安装包仍需使用原来的 com.tpschedule.app 包名、原签名,并递增构建号。当前本版是 0.7.6+24;其中版本号填写 0.7.6,版本序号(构建号)填写 24。下一次发布的确切数字以交付时提供的版本为准,不要仅修改后台数字而不重新构建APK。
登录后台填写:版本号、构建号、更新说明、公开HTTPS下载链接,点“保存并发布”。第一次可发布0.7.6/24,使公开信息与当前交付一致;已安装本版的用户不会收到同版更新提示。以后发布比24大的构建号时,已接入更新模块的APP启动或手动检查就会弹出更新说明。
同一版本号、同一构建号允许修改说明和下载链接;新增安装包应增加构建号。后台禁止降低构建号和版本号,并检测另一个页面修改,避免旧表单误覆盖。保存失败时原版本保留。新版本号应遵循 数字.数字.数字,不带V或+构建号。
更新提示是启动/手动联网检查,并非APP关闭后的系统通知,也不静默安装。用户点击立即更新后通过浏览器下载并按Android提示安装,APP不申请“安装未知应用”权限。需要允许浏览器安装来源时由Android和浏览器处理。
6. 第一次如何让同学接入
0.7.5及之前的APP没有检查更新代码,服务器无法给它们凭空补上。第一次仍需手动分发、覆盖安装0.7.6;之后这些用户才能收到你在后台发布的后续版本。不要卸载旧版,原包名、签名一致时覆盖安装保留本机课表。
维护和备份
正常更新服务代码:保留.env和数据卷,在原目录执行 docker compose up -d --build。更新后台密码和版本文件不要放进Git或聊天;备份现有数据卷时保持原Compose归属。磁盘或JSON损坏会返回503,不会伪装成没有更新或自动清空。后台会话8小时有效,登录有尝试次数限制;退出清除当前浏览器的登录Cookie。
API约定
已发布时返回200及以下JSON,响应禁止缓存。APP只在build_number大于自身构建号时提示,版本文本用于显示;跨应用、格式错误、HTTP错误、重定向或超过64KiB的响应都不会被当作更新成功。
{"schema_version":1,"application_id":"com.tpschedule.app","latest":{"version":"0.7.6","build_number":24,"notes":"新增启动与手动检查更新。","download_url":"https://example.com/TPSchedule-0.7.6.apk","published_at":"2026-10-24T00:00:00+00:00"}}
未部署/断网时自动检查不提示错误,手动检查显示失败原因;不影响已有课表或登录。下载链接只能用HTTPS,不能包含用户名/密码。发布信息中的更新说明在后台转义显示,APP按纯文本呈现。