71 lines
3.3 KiB
Markdown
71 lines
3.3 KiB
Markdown
|
|
# 1Panel 配置 / 安装向导 / nx update 根治设计
|
|||
|
|
|
|||
|
|
| 项 | 内容 |
|
|||
|
|
|----|------|
|
|||
|
|
| 日期 | 2026-06-06 |
|
|||
|
|
| 状态 | 已实施 |
|
|||
|
|
| 动机 | 三路审计发现安装向导安全泄露、配置不一致、`nx update` 无门控与回滚 |
|
|||
|
|
|
|||
|
|
## 背景与目标
|
|||
|
|
|
|||
|
|
生产 1Panel+Docker 链路曾出现:`nx update` 覆盖 Redis URL、`GET /state` 泄露 `install_token`/`redis_pass`、`init-db` MySQL 2003 分支 NameError、升级无镜像自检与健康回滚。
|
|||
|
|
|
|||
|
|
**目标**:在不改向导步骤数、不引入新依赖前提下,根治上述问题并补齐运维文档。
|
|||
|
|
|
|||
|
|
## 方案对比
|
|||
|
|
|
|||
|
|
| 维度 | 最小修补 | 根治(选定) |
|
|||
|
|
|------|----------|--------------|
|
|||
|
|
| `/state` | 仅删两个字段 | 白名单 `_public_install_state` + `has_token` |
|
|||
|
|
| `nx update` | 手工回滚 | 镜像 `import` 门控 + tag 回滚 + 健康失败自动恢复 |
|
|||
|
|
| 配置一致性 | 文档说明 | PENDING 回写、卷双写、Compose 去重、healthcheck 对齐 |
|
|||
|
|
| 备份失败 | 中止升级 | 默认 WARN 继续;`--require-backup` 可强制中止 |
|
|||
|
|
|
|||
|
|
## 选定方案
|
|||
|
|
|
|||
|
|
### A. 安装向导
|
|||
|
|
|
|||
|
|
- `init-db`:`db_port = int(req.db_port)`,修复 `_mysql_connect_error_detail` NameError。
|
|||
|
|
- `GET /state`:仅返回 `_INSTALL_STATE_PUBLIC_KEYS`;有 token 时设 `has_token: true`。
|
|||
|
|
- 前端:`sessionStorage` 暂存 token;无 token 时步骤 4 友好提示。
|
|||
|
|
- `connection-check` 修复 Redis 后 `_clear_state_redis_pass()`。
|
|||
|
|
|
|||
|
|
### B. 配置一致性
|
|||
|
|
|
|||
|
|
- `set_install_complete()`:检测到 `.install_locked` 时将 `NEXUS_INSTALL_WIZARD_PENDING=0` 写入 `docker/.env.prod`。
|
|||
|
|
- `sync_env_prod_to_volume()`:已锁定且 `docker/.env.prod` 密钥/URL 变更时同步至 `nexus-state` 卷。
|
|||
|
|
- `docker-compose.1panel.yml` 移除重复 `NEXUS_1PANEL_*` environment。
|
|||
|
|
- `docker-compose.prod.yml` healthcheck 与 `Dockerfile.prod` 对齐。
|
|||
|
|
- 文档注明 `NEXUS_REDIS_URL` 不经 Compose 注入。
|
|||
|
|
|
|||
|
|
### C. nx update 门控与回滚
|
|||
|
|
|
|||
|
|
1. 升级前 `tag_rollback_image` → `nexus-prod-nexus:rollback`
|
|||
|
|
2. `compose build` → `gate_new_image_import`(`python -c "import server.main"`)
|
|||
|
|
3. `compose up -d --no-build`
|
|||
|
|
4. `verify_health` 失败 → `rollback_compose_upgrade` + 退出非 0
|
|||
|
|
5. `backup_mysql` 失败默认 WARN;`--require-backup` 时中止
|
|||
|
|
6. `resolve_nexus_redis_url`:容器改名时迁移 `redis://:pass@` 至新 host
|
|||
|
|
7. `sync-install-wizard-to-container.sh` 仅在 install.html 非 200 时执行,失败可见
|
|||
|
|
8. `update.sh` 管道执行时 ROOT 回退 `/opt/nexus`
|
|||
|
|
|
|||
|
|
## 接口 / 数据模型
|
|||
|
|
|
|||
|
|
- `GET /api/install/state` 响应不再含 `install_token`、`redis_pass`;可选 `has_token: boolean`。
|
|||
|
|
- 无 DB 迁移;无新环境变量(沿用 `NEXUS_PUBLISH_PORT`、`NEXUS_INSTALL_WIZARD_PENDING`)。
|
|||
|
|
|
|||
|
|
## 安全与性能约束
|
|||
|
|
|
|||
|
|
- 白名单脱敏为强制;`sessionStorage` 仅当前标签页,锁定后 state 文件删除。
|
|||
|
|
- 镜像门控增加约数秒构建后延迟;回滚依赖升级前 tag 成功。
|
|||
|
|
- 卷双写仅在已锁定且 prod 密钥/URL 非空时执行。
|
|||
|
|
|
|||
|
|
## 验收标准
|
|||
|
|
|
|||
|
|
- [ ] `pytest tests/test_security_unit.py` 通过
|
|||
|
|
- [ ] `ruff check server/ --select F` 无错误
|
|||
|
|
- [ ] `GET /api/install/state` 无敏感字段
|
|||
|
|
- [ ] `nx update` 门控失败不切换容器;健康失败自动回滚
|
|||
|
|
- [ ] 已锁定主机 `NEXUS_INSTALL_WIZARD_PENDING=0`
|
|||
|
|
- [ ] Redis 容器改名后 URL 保留密码
|