Files
Nexus/docs/project/nexus-1panel-operations-knowledge.md
T
Nexus Deploy 9d9fbc62f5 docs: add 1Panel operations knowledge SSOT and Redis test script
Consolidate install wizard, networking, URL formats, and troubleshooting
into docs/project/nexus-1panel-operations-knowledge.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 07:08:42 +08:00

378 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Nexus 6.0 — 1Panel + Docker 运维知识文档
| 项 | 内容 |
|----|------|
| 版本 | 2026-06-06 |
| 读者 | 运维、接续开发、AI Agent |
| 定位 | **1Panel 生产部署 SSOT**(安装向导、网络、MySQL/Redis、日常 nx update |
| 关联 | [deploy/README-1panel.md](../../deploy/README-1panel.md) · [nexus-functional-development-guide.md](nexus-functional-development-guide.md) · [2026-06-04-1panel-docker-production.md](../design/plans/2026-06-04-1panel-docker-production.md) |
---
## 1. 架构总览
### 1.1 生产拓扑(1Panel
```mermaid
flowchart LR
Internet --> OpenResty["OpenResty (host)"]
OpenResty -->|"127.0.0.1:8600"| Nexus["Nexus 容器"]
Nexus -->|"1Panel-mysql-xxxx:3306"| MySQL["1Panel MySQL"]
Nexus -->|"1Panel-redis-xxxx:6379"| Redis["1Panel Redis"]
Nexus --- VolState["卷 nexus-state (.env)"]
Nexus --- VolData["卷 nexus-web-data"]
MySQL --- Net["1panel-network"]
Redis --- Net
Nexus --- Net
```
**铁律**[1Panel 官方说明](https://github.com/1Panel-dev/1Panel/issues/11676)):
- 应用商店 MySQL/Redis 在 **`1panel-network`** 上,容器间用 **容器名** 通信。
- **禁止**在 Nexus 容器内用 `127.0.0.1``localhost``host.docker.internal` 连 1Panel MySQL/Redis。
- OpenResty 在宿主机网络,反代目标为 **`http://127.0.0.1:8600`**。
### 1.2 仓库关键目录
| 路径 | 职责 |
|------|------|
| `server/` | FastAPI 后端;`api/install.py` = 安装向导 API |
| `frontend/` | Vue 3 SPA 源码(14 页) |
| `web/app/` | 构建产物;**`install.html` 为独立静态页**Alpine.js,不经 Vite 路由) |
| `web/data/` | 运行时:`config.json``1panel-hosts.json` |
| `deploy/` | 1Panel 安装/升级、`nx`、验收与修复脚本 |
| `docker/` | `docker-compose.prod.yml``entrypoint.sh``.env.prod` |
| `Dockerfile.prod` | 多阶段:npm build + Python 镜像 |
### 1.3 两套 Compose
| 文件 | 服务 |
|------|------|
| `docker-compose.yml` | 本地 devnexus + mysql + redis |
| `docker-compose.prod.yml` | **生产:仅 nexus** |
| `docker-compose.1panel.yml` | 叠加:nexus 加入 `1panel-network` |
---
## 2. 启动模式与 `.env` 生命周期
### 2.1 安装模式 vs 正常模式
`server/main.py``is_install_mode()`**运行时**检测 `/app/.env` 是否存在。
| 模式 | 条件 | 可用能力 |
|------|------|----------|
| 安装模式 | 无 `/app/.env` | `/api/install/*``/app/install.html`、静态、`/health` |
| 正常模式 | 有完整 `.env` | 全 API、WebSocket、后台任务 |
### 2.2 配置存储四层
| 层级 | 位置 | 写入方 |
|------|------|--------|
| Compose 环境 | 宿主机 `docker/.env.prod` | `nexus-1panel.sh install` / `generate_nexus_secrets.py` |
| 应用根 | 容器 `/app/.env` | 安装向导步骤 3 `init-db` |
| 持久卷 | `nexus-state``/var/lib/nexus/.env` | `entrypoint.sh` 退出时同步 |
| Web 数据 | `nexus-web-data``/app/web/data/` | `config.json``1panel-hosts.json` |
**不可从 DB settings 覆盖**`SECRET_KEY``API_KEY``ENCRYPTION_KEY``DATABASE_URL`
### 2.3 Docker 安装状态机
```
install --fresh
→ docker/.env.prod: NEXUS_INSTALL_WIZARD_PENDING=1 + 预生成三密钥
→ entrypoint 不写 /app/.env,不阻塞等待 MySQL/Redis
浏览器步骤 3 init-db
→ 写 /app/.env、config.json、settings、.install_state.json
步骤 4 create-admin
→ 写 admins,自动 lock.install_locked
entrypoint EXIT trap
→ /app/.env 复制到 nexus-state
```
**重要**:仅删除 1Panel 里的 MySQL 库 **不会** 清除 `/app/.env`;向导会提示「系统已初始化,无法重复执行数据库安装」。重装需删卷内 `.env` 并设 `NEXUS_INSTALL_WIZARD_PENDING=1`(见 §7.6)。
---
## 3. 安装向导(5 步)
### 3.1 流程与 API
| 步 | UI | API | 说明 |
|----|-----|-----|------|
| 1 | 欢迎 | — | 准备项 |
| 2 | 环境检测 | `GET /api/install/env-check` | TCP 探测 MySQL/Redis;返回 `docker_defaults` |
| 3 | 数据库配置 | `POST /api/install/test-credentials` | **必须先检测账号密码** |
| 3 | 初始化 | `POST /api/install/init-db` | 建表、三写、发 `install_token`**.env 已存在则 403** |
| 4 | 管理员 | `GET /api/install/connection-check` | 读 `.env` 验 MySQL+Redis |
| 4 | 创建 admin | `POST /api/install/create-admin` | 需 `install_token` |
| 5 | 完成 | `POST /api/install/lock`(兜底) | 写 `.install_locked` |
辅助:`GET /status``GET /state`(断点续装)。
实现文件:`server/api/install.py``web/app/install.html`
### 3.2 步骤 3 表单(1Panel 正确填法)
| 字段 | MySQL | Redis |
|------|-------|-------|
| 主机 | `1Panel-mysql-xxxx` | `1Panel-redis-xxxx` |
| 端口 | `3306` | `6379` |
| 库名/用户 | `nexus` / `nexus` | 库号 `0` |
| 用户名 | — | **`root`**1Panel Redis ACL[官方文档](https://docs.1panel.pro/v2/user_manual/databases/redis/) |
| 密码 | 1Panel「数据库」里建的 nexus 密码 | 1Panel Redis **应用参数**中的随机密码 |
### 3.3 Docker 预填来源
优先级(`_onepanel_service_host`):
1. 环境变量 `NEXUS_1PANEL_DB_HOST` / `NEXUS_1PANEL_REDIS_HOST`
2. `/app/web/data/1panel-hosts.json``nx update` 写入卷)
3. 回退 `host.docker.internal`**1Panel 场景错误**
`env-check``NEXUS_DOCKER_WRITE_ENV=1` 时返回 `docker_defaults`,含 `redis_user: "root"`。前端会覆盖 stale 的 `127.0.0.1` / `host.docker.internal`
### 3.4 连接 URL 格式(必读)
**MySQL**(写入 `NEXUS_DATABASE_URL`):
```
mysql+aiomysql://nexus:密码@1Panel-mysql-xxxx:3306/nexus
```
**Redis**(写入 `NEXUS_REDIS_URL`)— `server/api/install.py` `_build_redis_url`
| 场景 | URL 格式 |
|------|----------|
| 1Panel(推荐) | `redis://root:密码@1Panel-redis-xxxx:6379/0` |
| 仅 requirepass、无用户名 | `redis://:密码@1Panel-redis-xxxx:6379/0` |
| 无密码 | `redis://1Panel-redis-xxxx:6379/0` |
**历史 bug807f4c2 前)**:生成 `redis://密码@host` 会把密码当成**用户名**,导致 `invalid username-password pair or user is disabled`。升级后须 `git pull` + `sync-install-wizard-to-container.sh`
---
## 4. 1Panel 部署流程
### 4.1 前置
1. 安装 1Panel + Docker
2. 应用商店安装 **MySQL**、**Redis**(自动创建 `1panel-network`
3. 1Panel「数据库」:库 `nexus`、用户 `nexus`(仅授权 `nexus` 库)
4. 记录 Redis 应用参数中的 **root 密码**
### 4.2 安装 Nexus
```bash
# 新机(curl
curl -fsSL "http://66.154.115.8:3000/admin/Nexus/raw/branch/main/deploy/quick-install.sh" | bash
# 或已有仓库
cd /opt/nexus && bash deploy/install-nexus-fresh.sh --skip-clone
```
完成后:`https://<域名>/app/install.html`
### 4.3 `nx update` 自动 syncb25d079+
`deploy/nexus-1panel.sh` 在 install/upgrade 时:
1. `detect-1panel-services.sh` 探测容器名
2. 写入 `docker/.env.prod``NEXUS_1PANEL_*_HOST``NEXUS_REDIS_URL=redis://容器:6379/0`**无密码**,密码由向导填)
3. `write_1panel_hosts_volume``1panel-hosts.json`
4. 若存在 `1panel-network`,叠加 `docker-compose.1panel.yml`
### 4.4 OpenResty
- 1Panel → 网站 → 反代 `http://127.0.0.1:8600`
- HTTPS Let's Encrypt
- 参考:`deploy/1panel/openresty-nexus.conf.example``/ws/` 超时 ≥ 3600s
- **禁止**脚本修改 `/opt/1panel/apps/openresty/`
### 4.5 资源档位
| Profile | 说明 |
|---------|------|
| `1c4g` | 小机 |
| `2c8g` | 默认 |
| `4c16g` | `--profile 4c16g` |
持久化:`docker/.host-profile`
---
## 5. 日常运维:`nx` 与 `update`
| 命令 | 等价 |
|------|------|
| `nx` | 交互菜单 |
| `nx update` | `deploy/update.sh``nexus-1panel.sh upgrade` |
| `nexus-update` | 同上 |
**upgrade 顺序**`git fetch` → 可选 MySQL 备份 → `git reset --hard origin/main``sync_1panel_service_hosts``compose up -d --build``sync-install-wizard-to-container.sh``/health` 验收。
| 参数 | 含义 |
|------|------|
| `--check` | 仅查 Git |
| `--no-cache` | 无缓存重建镜像 |
| `--no-backup` | 跳过 mysqldump |
| `--prune` | 清理悬空镜像 |
---
## 6. 脚本速查
| 脚本 | 用途 |
|------|------|
| [deploy/README-1panel.md](../../deploy/README-1panel.md) | 速查表 |
| `verify-1panel-install-wizard.sh` | 服务器一键验收 |
| `detect-1panel-services.sh` | 输出 `NEXUS_1PANEL_*_HOST` |
| `fix-1panel-mysql-grant.sh` | 修复 MySQL 1045`nexus@'%'` |
| `test-1panel-redis.sh` | **Redis 多格式认证诊断** |
| `sync-install-wizard-to-container.sh` | 热同步 `install.html` + `install.py` |
| `uninstall-mysql-compose.sh` | 清理旧内置 MySQL 栈 |
---
## 7. 故障排查决策树
### 7.1 Redis 认证失败
**症状**`invalid username-password pair` / `NOAUTH` / `wrongpass`
```
1. 主机是否为 1Panel-redis-xxxx?(不是 127.0.0.1
2. 用户名是否 root?(1Panel 默认 ACL 用户)
3. 密码是否与 1Panel → Redis → 参数 一致?
4. 代码是否 ≥ 807f4c2?(URL 须 redis://root:pass@ 或 redis://:pass@
5. 运行诊断:
cd /opt/nexus && bash deploy/test-1panel-redis.sh
```
**在 Redis 容器内验证**
```bash
REDIS=$(docker ps --format '{{.Names}}' | grep -i '1Panel-redis' | head -1)
docker exec -it "$REDIS" redis-cli -u "redis://root:你的密码@127.0.0.1:6379" ping
# 期望 PONG
```
**查真实配置**(密码与 ACL):
```bash
ls /opt/1panel/apps/redis/
grep -E 'requirepass|user ' /opt/1panel/apps/redis/*/conf/redis.conf 2>/dev/null
```
**修正已有 `.env`(步骤 3 已执行过)**
```bash
NEXUS=$(docker ps --format '{{.Names}}' | grep nexus-prod-nexus | head -1)
REDIS=$(grep '^NEXUS_1PANEL_REDIS_HOST=' /opt/nexus/docker/.env.prod | cut -d= -f2)
docker exec "$NEXUS" sed -i "s|^NEXUS_REDIS_URL=.*|NEXUS_REDIS_URL=\"redis://root:你的密码@${REDIS}:6379/0\"|" /app/.env
docker restart "$NEXUS"
# 向导步骤 4 → 重新检测连接
```
### 7.2 MySQL 1045
**症状**`Access denied for user 'nexus'@'172.18.x.x'`
- TCP 已通,但用户仅 `nexus@localhost`
- 修复:`bash deploy/fix-1panel-mysql-grant.sh`(需 1Panel MySQL **root** 密码,非 nexus 用户)
### 7.3 host.docker.internal
**症状**`Can't connect to MySQL/Redis on 'host.docker.internal'`
```bash
cd /opt/nexus
bash deploy/detect-1panel-services.sh
nx update --no-cache
bash deploy/verify-1panel-install-wizard.sh
```
### 7.4 系统已初始化,无法重复执行数据库安装
- `/app/.env` 已存在,**不要**再点步骤 3 初始化
- 若 Redis 错:改 `.env``NEXUS_REDIS_URL`(§7.1)→ 步骤 4 重检
- 若需完全重装:
```bash
NEXUS=$(docker ps --format '{{.Names}}' | grep nexus-prod-nexus | head -1)
docker exec "$NEXUS" rm -f /app/.env /app/.install_state.json /app/.install_locked
docker run --rm -v nexus-prod_nexus-state:/data alpine:3.19 rm -f /data/.env
# 确认 docker/.env.prod 中 NEXUS_INSTALL_WIZARD_PENDING=1
nx update --no-cache
```
### 7.5 外网 HTTPS 失败、本机 8600 正常
- 配置 OpenResty 反代 + SSL
- `curl -s http://127.0.0.1:8600/health``ok`
- `curl -sk https://域名/health` → 应 `ok`
### 7.6 install.html 非 200
```bash
bash deploy/sync-install-wizard-to-container.sh
# 或 nx update --no-cache
```
---
## 8. 验收清单
```bash
cd /opt/nexus && bash deploy/verify-1panel-install-wizard.sh
```
关键 `[PASS]`
- Git ≥ `b25d079`1Panel sync
- `NEXUS_1PANEL_DB_HOST` / `NEXUS_1PANEL_REDIS_HOST`
- Nexus 在 `1panel-network`
- `/app/.env` 不存在(安装模式)或连接检测全绿
- `env-check``docker_defaults.db_host``1Panel-mysql-*`
浏览器:步骤 3 **先检测** → 初始化 → 步骤 4 创建 admin → `/app/` 登录。
---
## 9. 提交修复索引
| 提交 | 主题 |
|------|------|
| `b25d079` | `nx update` sync 1Panel 容器名;upgrade 补 `sync_1panel_service_hosts` |
| `d0544c9` | `fix-1panel-mysql-grant.sh`MySQL 1045 友好错误 |
| `da061d3` | 步骤 3 `test-credentials` 门禁 |
| `807f4c2` | Redis URL `redis://:pass@` / `redis://root:pass@``redis_user` 字段 |
---
## 10. 与功能开发 SSOT 的差异
| 点 | `nexus-functional-development-guide.md` §16 | 1Panel 实装 |
|----|---------------------------------------------|-------------|
| 步骤 2/3 | 与 init-db 合并描述 | 步骤 2 仅 env-check;步骤 3 含 test-credentials |
| 配置三写 | 提及 `config.php` | 现为 `config.json` |
| 生产部署 §18 | Supervisor + 宝塔 | 以 `nexus-1panel.sh` / `nx` 为主 |
| Redis 主机 | 泛化为 localhost | **1Panel 必须容器名 + root 用户** |
---
## 11. 相关文档
- [nexus-functional-development-guide.md](nexus-functional-development-guide.md) — 全栈功能 SSOT
- [nexus-functional-development-guide-appendix.md](nexus-functional-development-guide-appendix.md) — API 附录
- [production-verification-checklist.md](production-verification-checklist.md) — L5
- [linux-dev-paths.md](linux-dev-paths.md) — 本地路径
- [../changelog/](../changelog/) — 按日变更记录
---
*本文档随 1Panel 部署实践更新;代码行为以 `server/api/install.py` 与 `deploy/nexus-1panel.sh` 为准。*