From 227028f499b04fdbcaa844820957037d961b308d Mon Sep 17 00:00:00 2001 From: leefer Date: Thu, 30 Jul 2026 11:15:41 +0800 Subject: [PATCH] rebuild(deploy): make NAS preflight reversible --- next/.env.example | 2 ++ next/compose.yaml | 6 ++++-- next/docs/deployment.md | 12 ++++++++++-- next/docs/final/cutover-checklist.md | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/next/.env.example b/next/.env.example index 9f8aea8..449808e 100644 --- a/next/.env.example +++ b/next/.env.example @@ -1,3 +1,5 @@ APP_ENCRYPTION_KEY=replace-with-a-persistent-fernet-key +APP_IMAGE=xiaobai-review-next:preflight +APP_PUBLISH_PORT=8876 APP_LOG_LEVEL=INFO APP_TIMEZONE=Asia/Shanghai diff --git a/next/compose.yaml b/next/compose.yaml index 0b34ae6..faf58d4 100644 --- a/next/compose.yaml +++ b/next/compose.yaml @@ -2,10 +2,11 @@ services: web: build: context: . - image: xiaobai-review-next:local + image: ${APP_IMAGE:-xiaobai-review-next:local} + init: true restart: unless-stopped ports: - - "8765:8765" + - "${APP_PUBLISH_PORT:-8876}:8765" env_file: - .env environment: @@ -24,3 +25,4 @@ services: - no-new-privileges:true cap_drop: - ALL + stop_grace_period: 30s diff --git a/next/docs/deployment.md b/next/docs/deployment.md index 58c35fc..005ba9a 100644 --- a/next/docs/deployment.md +++ b/next/docs/deployment.md @@ -7,7 +7,8 @@ 1. 将 `.env.example` 复制为 `.env`,写入固定的 Fernet `APP_ENCRYPTION_KEY`。该密钥必须与迁移旧数据时使用的密钥一致。 2. 创建 `data/private-mentor-skills/`,把不公开的 Skill 放在该持久化目录;镜像内只含公开 Skill。 3. 先在独立目录运行迁移,并查看报告中的迁移数、主动跳过项、完整性和校验和。 -4. 使用尚未占用的端口启动新容器并完成验收。不要停止旧容器。 +4. 保持`APP_PUBLISH_PORT=8876`在临时端口启动新容器并完成验收。不要停止旧容器,也不要提前改成正式端口。 +5. `APP_IMAGE`使用可回溯的验收标签;正式切换和回退均不得只依赖浮动的`latest`标签。 ```powershell $env:APP_ENCRYPTION_KEY='<现有固定密钥>' @@ -20,6 +21,10 @@ docker compose build docker compose up -d ``` +启动后先检查`http://NAS地址:8876/api/health`,再访问`http://NAS地址:8876/`完成真实账号抽验。 +宿主`data`目录必须允许镜像中的非root用户写入;若启动日志出现权限错误,先用 +`docker compose run --rm web id`确认容器UID/GID,再只修正该绑定目录的所有权,不得改为root运行容器。 + `legacy_migration` 以只读 URI 打开旧库,可重复执行;会保留用户编号和密码散列,不迁移会话。旧的每用户 LLM 配置和可由正式数据源重建的原始因子表会明确记录为主动跳过,不会进入新运行时。 ## 备份 @@ -55,11 +60,14 @@ python -m tools.restore ` ## 升级与回退 1. 升级前生成一致备份,记录当前镜像标签与数据库 migration 版本。 -2. 用新镜像启动独立验收容器;健康检查通过后再切换反向代理或宿主端口。 +2. 用固定`APP_IMAGE`标签和临时`APP_PUBLISH_PORT=8876`启动独立验收容器;健康检查通过后再切换反向代理或宿主端口。 3. 代码回退只切换至旧镜像,不自动降级数据库。 4. 若新 migration 与旧镜像不兼容,使用升级前的整套备份恢复到独立目录,再启动旧镜像。 5. NAS 正式切换属于单独人工确认项,本仓库脚本不会自动执行切换。 +若最终采用宿主端口直连,只有在旧容器停止写入且用户确认切换窗口后,才把`APP_PUBLISH_PORT` +改为`8765`并重新创建新容器。若通过反向代理切流,则继续保留临时宿主端口,由反向代理修改上游。 + ## 本机验证边界 开发机未安装 Docker 时仍可执行全部 Python、前端构建、迁移和备份恢复测试,但不能声称镜像已经实际构建或容器健康检查已经运行。最终切换前应在有 Docker 的 NAS 或预发布机补做 `docker compose build`、只读文件系统、数据卷写入和重启恢复验证。 diff --git a/next/docs/final/cutover-checklist.md b/next/docs/final/cutover-checklist.md index ffd9fcf..40fad3f 100644 --- a/next/docs/final/cutover-checklist.md +++ b/next/docs/final/cutover-checklist.md @@ -8,7 +8,8 @@ - [ ] 验证容器以非root、只读根文件系统启动,`/app/data`可写,健康检查稳定。 - [ ] 验证容器重启后账号、行情、自选、复盘、会员、模型、问天和选股记录不丢失。 - [ ] 在NAS受控目录完成数据库、环境密钥和私有Skill整套备份,并做一次独立恢复。 -- [ ] 为新容器分配临时端口,完成真实数据的日间/夜间、1080P/4K/390px抽验。 +- [ ] 保持`APP_PUBLISH_PORT=8876`启动新容器,完成真实数据的日间/夜间、1080P/4K/390px抽验。 +- [ ] 记录实际`APP_IMAGE`标签,确认该标签可在不重新构建的情况下用于回退演练。 - [ ] 用户明确确认最终切换窗口。 ## 切换步骤