# 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 保留密码
