diff --git a/docs/release/20260708/PR-MERGE-说明-20260709.md b/docs/release/20260708/PR-MERGE-说明-20260709.md new file mode 100644 index 00000000..d6c99750 --- /dev/null +++ b/docs/release/20260708/PR-MERGE-说明-20260709.md @@ -0,0 +1,362 @@ +# Nexus PR 合并说明:宝塔 Session 稳定性修复与 /app-v2 双后台 + +> 目标分支:`release/20260708-axs` +> 本地提交基线:`1933f0af6e647818e716ed194cdb92d7ed7bb47a` +> 编写日期:2026-07-09 +> 推荐用途:复制本文件核心内容到 Gitea Pull Request 描述,用于合并评审。 + +## 1. 合并结论 + +建议合并。该分支主要解决 Nexus 的宝塔一键登录在 1~2 小时后刷新掉线的问题,同时加入 `/app-v2` 第二后台与发布制品化工具链。 + +本分支不是单点热修,而是一组围绕“宝塔长期登录稳定性 + 新后台并行上线 + 发布可验证”的完整改进: + +- 一键登录前自动检测并修复宝塔 `task.py` 中硬编码 `3600` 秒清理 `tmp_login` session 的问题; +- 对同一台宝塔服务器的一键登录生成过程加锁,避免并发打开多个宝塔时 tmp token / session 互相覆盖; +- 新增 `/app-v2` 第二后台,保持旧后台 `/app/` 可继续使用,支持渐进替换; +- 增强发布包、发布前检查、发布验证和回滚脚本; +- 补齐代码审查、调用链、安全巡检、发布记录等文档。 + +## 2. 背景问题 + +用户实际现象: + +```text +Nexus 一键登录宝塔成功 +同时打开多台/多窗口宝塔 +约 1~2 小时后刷新页面陆续掉线 +``` + +根因链路: + +```text +Nexus 一键登录成功 +→ 宝塔生成 tmp_login session 文件 +→ 宝塔 BT-Task 定时清理 session +→ 部分宝塔 task.py 硬编码超过 3600 秒删除 tmp_login session +→ 1~2 小时后刷新 +→ tmp_login session 已被删除 +→ 宝塔判定掉线 +``` + +此外,同时打开多个宝塔时,同一台宝塔如果被重复触发一键登录,可能出现登录 URL / tmp token 生成冲突,因此本分支加入了分布式锁与远端 bootstrap 锁。 + +## 3. 本次核心改动 + +### 3.1 宝塔一键登录长期不掉线修复 + +关键能力: + +- 登录前自动检测宝塔 `task.py` 是否存在 hardcoded `3600` 清理逻辑; +- 自动修复为读取 `public.get_session_timeout()`,无法读取时使用默认 `86400`; +- 对新增宝塔也执行兜底检测/修复; +- 一键登录前再次兜底检测/修复,避免漏修服务器; +- 修复过程使用 SSH bootstrap,包含远端 `flock`、`mktemp`、atomic replace,降低并发和半写入风险; +- 同一宝塔登录 URL 生成加 Redis 分布式锁,防止同一服务器被并发打开时 token/session 互相覆盖。 + +重点文件: + +```text +server/application/services/btpanel_service.py +server/infrastructure/btpanel/login_url_lock.py +server/infrastructure/btpanel/bootstrap_lock.py +server/infrastructure/btpanel/ssh_bootstrap.py +server/api/btpanel.py +``` + +相关测试: + +```text +tests/test_btpanel_bootstrap_lock.py +tests/test_btpanel_get_config.py +tests/test_btpanel_login_url.py +tests/test_btpanel_login_url_route.py +tests/test_btpanel_ssh_bootstrap.py +tests/test_btpanel_temp_login_ttl.py +``` + +### 3.2 `/app-v2` 第二后台 + +新增第二后台,路径为: + +```text +/app-v2/ +``` + +设计目标: + +- 不替换旧后台 `/app/`,双后台并行; +- 保留原功能入口,逐步迁移; +- 更现代、更快、更适合后续 UI 重构; +- 全局 API Key 等敏感值不直接展示真实值。 + +技术栈: + +```text +React + TypeScript + Vite +shadcn/ui + Tailwind +TanStack Query +TanStack Table +Zustand +``` + +重点文件: + +```text +frontend-v2/ +web/app-v2/ +frontend-v2/scripts/scan-app-v2-sensitive.mjs +server/main.py +Dockerfile +Dockerfile.prod +``` + +### 3.3 发布制品化与验证工具链 + +本分支加入/增强了发布包生成、扫描、元数据、发布前检查和发布辅助脚本: + +```text +scripts/prepare_release_artifact.py +scripts/generate_release_bundle.py +scripts/scan_release_bundle.py +scripts/write_release_metadata.py +scripts/publish_release_bundle.py +scripts/check_text_integrity.py +scripts/generate_release_diff.py +scripts/run_local_release_gate.py +``` + +服务器侧脚本: + +```text +deploy/preflight-release-host.sh +deploy/apply-release-bundle.sh +deploy/sync_webapp_to_container.sh +``` + +发布包: + +```text +C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz +``` + +SHA256: + +```text +46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b +``` + +## 4. 验证结果 + +本地 release gate 已通过: + +```text +Python py_compile +bash -n deploy shell +部署排除规则检查 +文本完整性检查 +/app-v2 build:safe +app-v2 sensitive scan +宝塔专项 pytest +发布辅助脚本测试 +``` + +测试结果: + +```text +65 passed +``` + +发布包验证: + +```text +size_mb=27.02 +entries=2409 +OK: release bundle looks clean +apply-release-bundle.sh --validate-only passed +metadata / .sha256 / tar 实际 SHA 一致 +``` + +重点人工验证建议: + +- `/app/` 旧后台可访问; +- `/app-v2/` 新后台可访问; +- 宝塔一键登录可打开; +- 同一台宝塔连续/并发触发一键登录不会互相覆盖; +- 新增宝塔在一键登录前会自动检测/修复 hardcoded `3600`; +- 典型宝塔登录 2 小时后刷新仍保持登录状态。 + +## 5. 合并风险与边界 + +### 5.1 主要风险 + +1. **宝塔远端 patch 风险** + 修复逻辑会通过 SSH 修改目标宝塔服务器上的 `task.py`。本项目定位中,管理员远程执行命令属于产品能力,因此这不是普通越权漏洞,但合并后需要继续保持审计日志与失败可见性。 + +2. **不同宝塔版本兼容性** + 部分宝塔版本 `task.py` 内容可能不同。当前逻辑已经使用检测/备份/原子替换/失败回退策略,但建议继续抽检更多系统版本。 + +3. **双后台静态资源体积** + 分支包含旧后台和新后台静态资源,仓库和发布包会变大。当前发布包约 27MB,可接受。 + +4. **远端批量修复节奏** + 线上 420 台里曾识别出 148 台存在 hardcoded_3600。合并后建议继续采用分批检测/修复,不建议一次性对全部服务器无观察窗口地全量变更。 + +### 5.2 不属于本次合并要解决的问题 + +- 不在本次合并中重构所有后台 UI; +- 不强制删除旧后台 `/app/`; +- 不改变 `script_service` 管理员远程执行命令的产品定位; +- 不依赖账号密码替代宝塔 API 登录;账号密码一键登录可作为后续增强方案单独设计。 + +## 6. 推荐合并方式 + +### 6.1 推荐路径 + +推荐在 Gitea 上创建 Pull Request: + +```text +source: release/20260708-axs +target: main +``` + +PR 地址: + +```text +https://axs.kuma1xn.vip/admin/Nexus/pulls/new/release/20260708-axs +``` + +建议标题: + +```text +release: 宝塔 Session 长期登录修复与 /app-v2 双后台 +``` + +建议合并策略: + +```text +Create merge commit +``` + +理由:本分支是发布型分支,包含后端修复、前端新增、发布脚本和文档。保留 merge commit 更方便后续定位整次发布。 + +### 6.2 合并前检查 + +合并前建议在 Gitea 页面确认: + +- 目标分支是 `main`; +- source 分支是 `release/20260708-axs`; +- 文件变更中包含 `docs/release/20260708/` 说明; +- 没有 `.venv`、`node_modules`、`.env`、`.pem` 等运行环境文件; +- PR 描述中粘贴本说明的第 1~8 节。 + +## 7. 合并后部署方式 + +### 7.1 仅上传 + preflight + +```cmd +cd /d C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 + +.venv-py312-codex\Scripts\python.exe scripts\publish_release_bundle.py ^ + --remote nexus ^ + --tarball C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ^ + --sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b +``` + +### 7.2 正式 apply + +preflight 无异常后再加 `--apply`: + +```cmd +.venv-py312-codex\Scripts\python.exe scripts\publish_release_bundle.py ^ + --remote nexus ^ + --tarball C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ^ + --sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b ^ + --apply +``` + +### 7.3 部署后验证 + +```cmd +.venv-py312-codex\Scripts\python.exe scripts\verify_online_release.py --base-url https://api.synaglobal.vip +``` + +期望: + +```text +OK: health +OK: /app +OK: /app-v2 +OK: online release verification passed +``` + +## 8. 回滚策略 + +如果合并后未部署: + +```text +在 Gitea revert merge commit 即可。 +``` + +如果已经部署: + +1. 使用 `deploy/apply-release-bundle.sh` 生成的备份目录回滚; +2. 恢复上一版 `/opt/nexus` 文件; +3. 重启 Nexus 服务/容器; +4. 验证 `/health`、`/app/`; +5. 如果问题只影响 `/app-v2/`,可临时隐藏 `/app-v2/` 路由或静态资源,不影响旧后台 `/app/`。 + +宝塔远端 `task.py` 修复属于向更长 session timeout 的兼容性修复。若个别宝塔异常,优先按单台服务器恢复宝塔备份文件,不建议全局回滚。 + +## 9. 文档索引 + +本分支已包含详细文档,集中在: + +```text +docs/release/20260708/ +``` + +建议优先阅读: + +```text +docs/release/20260708/Nexus-项目说明文档-20260708.md +docs/release/20260708/Nexus-release-index-20260708.md +docs/release/20260708/Nexus-release-ready-checklist-20260708.md +docs/release/20260708/Nexus-宝塔一键登录长期掉线修复方案与代码改进.md +docs/release/20260708/Nexus-app-v2-双后台实施说明-20260707.md +docs/release/20260708/Nexus-manual-deploy-commands-20260708.md +``` + +## 10. 可直接复制到 Gitea PR 的摘要 + +```markdown +## 合并摘要 + +本 PR 修复 Nexus 宝塔一键登录 1~2 小时后刷新掉线的问题,并新增 /app-v2 第二后台与发布制品化工具链。 + +### 核心改动 + +- 一键登录前自动检测/修复宝塔 task.py hardcoded 3600 清理 tmp_login session 的问题; +- 基于 public.get_session_timeout() 或默认 86400 延长 tmp_login session 有效期; +- 新增 Redis 分布式锁,避免同一宝塔并发生成登录 URL/token 互相覆盖; +- SSH bootstrap 使用 flock / mktemp / atomic replace 降低远端 patch 风险; +- 新增 /app-v2 第二后台,旧后台 /app/ 保留; +- 增强发布包生成、扫描、preflight、validate-only、apply 与回滚脚本; +- 补齐发布说明、调用链、安全巡检、宝塔修复记录等文档。 + +### 验证 + +- release gate 通过; +- 宝塔专项测试通过; +- 发布辅助脚本测试通过; +- 合计 65 passed; +- 发布包扫描通过; +- apply-release-bundle.sh --validate-only 通过; +- 发布包 SHA256: 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b。 + +### 风险 + +- 会通过 SSH 对目标宝塔服务器 task.py 做自动修复,已加入检测、备份、锁和原子替换; +- /app-v2 与 /app 双后台并行,不删除旧后台; +- 建议合并后先 preflight,再 apply,并对宝塔一键登录做 2 小时刷新验证。 +``` diff --git a/docs/release/20260708/README-Gitea发布说明-20260708.md b/docs/release/20260708/README-Gitea发布说明-20260708.md index 948555bc..a9f51e78 100644 --- a/docs/release/20260708/README-Gitea发布说明-20260708.md +++ b/docs/release/20260708/README-Gitea发布说明-20260708.md @@ -1,19 +1,25 @@ -# Nexus Gitea 发布说明(2026-07-08) +# Nexus Gitea 鍙戝竷璇存槑锛?026-07-08锛? -本目录收录本次 Nexus 发布、审查、宝塔 Session 修复、/app-v2 双后台、环境修复与发布验证相关说明文档。 +鏈洰褰曟敹褰曟湰娆?Nexus 鍙戝竷銆佸鏌ャ€佸疂濉?Session 淇銆?app-v2 鍙屽悗鍙般€佺幆澧冧慨澶嶄笌鍙戝竷楠岃瘉鐩稿叧璇存槑鏂囨。銆? -## 本次核心内容 +## 鏈鏍稿績鍐呭 -- 宝塔一键登录长期掉线修复:登录前自动检测/修复 hardcoded_3600,避免 tmp_login session 被 1 小时硬清。 -- 新增宝塔自动兜底:新增服务器和一键登录前都会进行 session 修复检测。 -- /app-v2 第二后台:React + TypeScript + Vite + shadcn/ui + Tailwind + TanStack Query/Table + Zustand。 -- 发布包与发布工具链:本地 release gate、bundle scan、validate-only 已通过。 +- 瀹濆涓€閿櫥褰曢暱鏈熸帀绾夸慨澶嶏細鐧诲綍鍓嶈嚜鍔ㄦ娴?淇 hardcoded_3600锛岄伩鍏?tmp_login session 琚?1 灏忔椂纭竻銆? +- 鏂板瀹濆鑷姩鍏滃簳锛氭柊澧炴湇鍔″櫒鍜屼竴閿櫥褰曞墠閮戒細杩涜 session 淇妫€娴嬨€? +- /app-v2 绗簩鍚庡彴锛歊eact + TypeScript + Vite + shadcn/ui + Tailwind + TanStack Query/Table + Zustand銆? +- 鍙戝竷鍖呬笌鍙戝竷宸ュ叿閾撅細鏈湴 release gate銆乥undle scan銆乿alidate-only 宸查€氳繃銆? -## 推荐入口文档 +## 鎺ㄨ崘鍏ュ彛鏂囨。 -- Nexus-项目说明文档-20260708.md +- Nexus-椤圭洰璇存槑鏂囨。-20260708.md - Nexus-release-index-20260708.md - Nexus-release-ready-checklist-20260708.md - Nexus-manual-deploy-commands-20260708.md -- Nexus-宝塔一键登录长期掉线修复方案与代码改进.md -- Nexus-app-v2-双后台实施说明-20260707.md +- Nexus-瀹濆涓€閿櫥褰曢暱鏈熸帀绾夸慨澶嶆柟妗堜笌浠g爜鏀硅繘.md +- Nexus-app-v2-鍙屽悗鍙板疄鏂借鏄?20260707.md + + +## 合并说明入口 + +- PR-MERGE-说明-20260709.md:用于 Gitea Pull Request 合并评审,可直接复制到 PR 描述。 +