Files
Nexus/docs/project/nexus-1panel-operations-knowledge.md
T
Nexus Deploy 5a56e5a8cb fix(1panel): 安装向导脱敏、配置一致性与 nx update 门控回滚
- /state 白名单脱敏;init-db db_port 修复;connection-check 后清空 redis_pass
- install.html sessionStorage token 与无 token 友好提示
- nx update: 镜像 import 门控、健康失败自动回滚、PENDING=0 回写、卷双写
- Redis 容器改名密码迁移;备份失败默认 WARN;update.sh 管道 ROOT 回退
2026-06-06 17:40:30 +08:00

15 KiB
Raw Blame History

Nexus 6.0 — 1Panel + Docker 运维知识文档

内容
版本 2026-06-06
读者 运维、接续开发、AI Agent
定位 1Panel 生产部署 SSOT(安装向导、网络、MySQL/Redis、日常 nx update
关联 deploy/README-1panel.md · nexus-functional-development-guide.md · 2026-06-04-1panel-docker-production.md

1. 架构总览

1.1 生产拓扑(1Panel

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 官方说明):

  • 应用商店 MySQL/Redis 在 1panel-network 上,容器间用 容器名 通信。
  • 禁止在 Nexus 容器内用 127.0.0.1localhosthost.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.json1panel-hosts.json
deploy/ 1Panel 安装/升级、nx、验收与修复脚本
docker/ docker-compose.prod.ymlentrypoint.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.pyis_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.json1panel-hosts.json

不可从 DB settings 覆盖SECRET_KEYAPI_KEYENCRYPTION_KEYDATABASE_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_lockedDocker 模式展示 1Panel 守护清单

辅助:GET /statusGET /state(断点续装;白名单脱敏,不含 install_token/redis_pass,有 token 时仅 has_token: true)。

实现文件:server/api/install.pyweb/app/install.html

3.2 步骤 3 表单(1Panel 正确填法)

字段 MySQL Redis
主机 1Panel-mysql-xxxx 1Panel-redis-xxxx
端口 3306 6379
库名 nexus 库号 0
用户名 nexus 1Panel Redis 无账号;向导仅填密码)
密码 1Panel「数据库」里建的 nexus 密码 1Panel Redis 应用参数中的口令

3.3 进程守护(1Panel Docker

层级 机制 说明
Layer 1 Compose restart: unless-stopped + healthcheck 容器崩溃自动拉起
Layer 2 Python self_monitor30s 向导完成后正常模式自动运行
Layer 3 宿主机 OpenResty + 可选 health_monitor.sh 反代 127.0.0.1:8600;见 deploy/1panel/openresty-nexus.conf.example

init-dbNEXUS_DOCKER_WRITE_ENV=1 时调用 _configure_docker_guardian在容器内写 Supervisor)。

3.4 Docker 预填来源

优先级(_onepanel_service_host):

  1. 环境变量 NEXUS_1PANEL_DB_HOST / NEXUS_1PANEL_REDIS_HOST
  2. /app/web/data/1panel-hosts.jsonnx update 写入卷)
  3. 回退 host.docker.internal1Panel 场景错误

env-checkNEXUS_DOCKER_WRITE_ENV=1 时返回 docker_defaults(主机/端口/库名,不含 Redis 用户名)。前端会覆盖 stale 的 127.0.0.1 / host.docker.internal,并隐藏 Redis 用户名字段。

3.5 连接 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://:密码@1Panel-redis-xxxx:6379/0(向导用户名留空)
1Panel ACL default redis://default:密码@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. 应用商店安装 MySQLRedis(自动创建 1panel-network
  3. 1Panel「数据库」:库 nexus、用户 nexus(仅授权 nexus 库)
  4. 记录 Redis 应用参数中的 连接口令(不是 MySQL 式账号)

4.2 安装 Nexus

# 新机(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 自动 sync2026-06-06 根治版)

deploy/nexus-1panel.sh 在 install/upgrade 时:

  1. detect-1panel-services.sh 探测容器名
  2. 写入 docker/.env.prodNEXUS_1PANEL_*_HOSTNEXUS_REDIS_URL 优先保留卷/向导中的 redis://:pass@host不经 Compose 注入容器
  3. write_1panel_hosts_volume1panel-hosts.json
  4. 若存在 1panel-network,叠加 docker-compose.1panel.yml(仅 networks,无重复 environment
  5. 已锁定sync_env_prod_to_volumedocker/.env.prod 三密钥 + NEXUS_REDIS_URL/NEXUS_DATABASE_URL 双写至 nexus-state
  6. 已锁定set_install_completeNEXUS_INSTALL_WIZARD_PENDING=0 回写 docker/.env.prod

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. 日常运维:nxupdate

命令 等价
nx 交互菜单
nx update deploy/update.shnexus-1panel.sh upgrade
nexus-update 同上

upgrade 顺序2026-06-06+):

git fetch → MySQL 备份(失败默认 WARN)→ git reset --hard
→ sync_1panel_service_hosts → sync_env_prod_to_volume
→ tag 当前镜像为 nexus-prod-nexus:rollback
→ compose build → 镜像门控 (import server.main)
→ compose up -d --no-build
→(仅 install.html 非 200 时)sync-install-wizard-to-container.sh
→ set_install_complete → verify_health(端口 NEXUS_PUBLISH_PORT
→ 健康失败:自动 tag rollback + up -d 回滚
参数 含义
--check 仅查 Git
--no-cache 无缓存重建镜像
--no-backup 跳过 mysqldump
--require-backup mysqldump 失败则中止升级
--prune 清理悬空镜像

推荐更新方式cd /opt/nexus && bash deploy/update.shcurl \| bash 会回退 /opt/nexus 并打印警告)。

5.1 密钥 / Redis URL 轮换(双写)

已锁定生产环境运行时以 卷内 /var/lib/nexus/.env 为准。轮换步骤:

  1. 修改宿主机 docker/.env.prodNEXUS_SECRET_KEY / NEXUS_API_KEY / NEXUS_ENCRYPTION_KEYNEXUS_REDIS_URL
  2. 执行 sudo nx update — 脚本 sync_env_prod_to_volume 会同步至卷
  3. 验收:docker exec <nexus> redis-cli -u "$URL" pingPONG/healthok

Redis 容器改名时,resolve_nexus_redis_url 会尝试将旧 URL 中的密码迁移到新 host。


6. 脚本速查

脚本 用途
deploy/README-1panel.md 速查表
verify-1panel-install-wizard.sh 服务器一键验收
detect-1panel-services.sh 输出 NEXUS_1PANEL_*_HOST
fix-1panel-mysql-grant.sh 修复 MySQL 1045nexus@'%'
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 Redis **无账号**,只填密码)
3. 密码是否与 1Panel → Redis → 参数 一致?
4. 运行 `bash deploy/test-1panel-redis.sh` 看哪种 URL 可用
5. 运行诊断:
   cd /opt/nexus && bash deploy/test-1panel-redis.sh

在 Redis 容器内验证

REDIS=$(docker ps --format '{{.Names}}' | grep -i '1Panel-redis' | head -1)
docker exec -it "$REDIS" redis-cli -u "redis://:你的密码@127.0.0.1:6379" ping
# 期望 PONG

查真实配置(密码与 ACL):

ls /opt/1panel/apps/redis/
grep -E 'requirepass|user ' /opt/1panel/apps/redis/*/conf/redis.conf 2>/dev/null

修正已有 .env(步骤 3 已执行过)

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://:你的密码@${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'

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 错:改 .envNEXUS_REDIS_URL(§7.1)→ 步骤 4 重检
  • 若需完全重装:
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/healthok
  • curl -sk https://域名/health → 应 ok

7.6 install.html 非 200

bash deploy/sync-install-wizard-to-container.sh
# 或 nx update --no-cache

8. 验收清单

cd /opt/nexus && bash deploy/verify-1panel-install-wizard.sh

关键 [PASS]

  • Git ≥ b25d0791Panel sync
  • NEXUS_1PANEL_DB_HOST / NEXUS_1PANEL_REDIS_HOST
  • Nexus 在 1panel-network
  • /app/.env 不存在(安装模式)或连接检测全绿
  • env-checkdocker_defaults.db_host1Panel-mysql-*

浏览器:步骤 3 先检测 → 初始化 → 步骤 4 创建 admin → /app/ 登录。


9. 提交修复索引

提交 主题
b25d079 nx update sync 1Panel 容器名;upgrade 补 sync_1panel_service_hosts
d0544c9 fix-1panel-mysql-grant.shMySQL 1045 友好错误
da061d3 步骤 3 test-credentials 门禁
807f4c2 Redis URL redis://:pass@ 修复(曾误加 root,已废弃)
3b2856f+ 自动解析 :pass@ / default;步骤 4 connection-check 可自愈 .env

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 必须容器名 + 仅密码(:pass@

11. 相关文档


本文档随 1Panel 部署实践更新;代码行为以 server/api/install.pydeploy/nexus-1panel.sh 为准。