Files
Nexus/CLAUDE.md
T
Your Name 0f02e047cc
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
docs: update deployment instructions for Vuetify SPA
- Split backend/frontend deploy steps
- Add deploy-frontend.sh one-liner reference
- Document AppAuthMiddleware 404 and stale HTML troubleshooting
- Remove obsolete dist copy instructions

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 13:25:33 +08:00

14 KiB
Raw Blame History

Nexus 6.0 — Project Memory

项目概述

Nexus 是一个 2000+ 服务器运维管理平台,从旧的 MultiSync (PHP + AdminLTE + pymysql) 完全重构为 Clean Architecture (FastAPI + Async SQLAlchemy + Redis + WebSocket + Telegram)。前端已全面迁移到 Tailwind CSS v4 + Alpine.jsPHP 依赖已移除。

仓库结构

  • 唯一仓库: Nexus (Gitea, 仓库地址在 .env 中配置)
  • 不再使用 multi-server-sync 仓库(旧项目,仅保留历史)
  • 部署路径: 由 NEXUS_DEPLOY_PATH 环境变量决定(安装向导自动写入 .env)
  • 域名/CORS: 由 NEXUS_CORS_ORIGINS 环境变量决定(安装向导自动写入)

目录结构 (仓库根目录)

Nexus/
├── server/            ← Python FastAPI后端 (Clean Architecture 4层)
│   ├── api/           ← API路由 (含 install.py 安装向导API)
│   ├── domain/        ← SQLAlchemy模型 (14张表)
│   ├── infrastructure/← SSH连接池 + Redis + Telegram
│   ├── background/    ← 后台任务 (心跳刷新/自检/调度/重试)
│   └── config.py      ← Pydantic Settings + MySQL覆盖
├── web/app/           ← Tailwind+Alpine.js 纯静态前端 (12个HTML页面)
│   ├── install.html   ← 安装向导 (5步)
│   ├── login.html     ← JWT登录+TOTP双因素
│   └── ...            ← index/servers/files/push/scripts等
├── deploy/            ← Supervisor配置 + Shell健康检查脚本
├── docs/              ← 项目文档
├── tests/             ← 测试
├── .env               ← NOT IN GIT (安装向导生成)
└── requirements.txt   ← Python依赖

启动模式

  • 安装模式 (无 .env): 仅 /api/install/ + 静态文件可用,其他路由返回503
  • 正常模式 (有 .env): 完整初始化 DB/Redis/后台任务

已确认的关键决策

决策 选择 原因
API_KEY 禁改,UI不显示 加密一致性 + 子服务器认证
SECRET_KEY 禁改 加密回退密钥
DATABASE_URL 禁改 启动必需
system_name/title 可改 前端显示
pool_size/overflow 可改 安装向导自动推荐
redis_url 可改 Redis连接
告警阈值 (CPU/mem/disk) 可改 监控参数 (默认80%)
Telegram配置 可改 告警推送
Agent心跳间隔 60s 不太频繁
Redis→MySQL刷新 10min 降低MySQL负载
心跳数据流 Agent→Redis→前端直读→10min→MySQL 前端实时, MySQL只存历史
告警推送 WebSocket→前端 + Telegram 即时感知
Python守护 3层: Supervisor + Python自检(30s) + Shell(cron 1min) 全覆盖
安装向导 install.html + FastAPI API 纯Python,无PHP依赖
配置源 安装向导→config.json+settings表(MySQL)+.env(Python) 三写一致
Agent告警心跳 CPU/内存>80% 或变化>10% 时主动上报 智能监控
仓库统一 所有代码统一在Nexus仓库 不再用两个仓库

实现状态 (Phase A+B+C+D+E) — ~99% 完成

已完成 (全部6步 + 技术债务 + UX增强)

模块 文件 说明
Step 0: 基础设施 Redis + WebSocket
E1 WebSocket推送 server/api/websocket.py alert/recovery/system broadcast
E2 心跳→Redis+告警 server/api/agent.py Redis write + threshold detection
E3 Redis→MySQL刷新 server/background/heartbeat_flush.py 10min batch
Step 1: 数据层 14张表
E4 load_settings_from_db server/config.py MySQL overrides mutable settings
Step 2: 认证层 JWT + TOTP
Step 3: Web SSH asyncssh + xterm.js
E5 asyncssh连接池 server/infrastructure/ssh/asyncssh_pool.py 引用计数模式
E6 WebSSH前端 web/app/terminal.html xterm.js + Koko协议 + 自动resize
Step 4: Sync引擎 4种同步模式
Step 5: 前端迁移 Tailwind+Alpine.js
E7 13个前端页面 web/app/*.html 含install.html安装向导
E8 安装向导API server/api/install.py 6端点, 无JWT, 临时引擎
E9 条件启动模式 server/main.py 无.env=安装模式
后台任务
E10 Python自检 server/background/self_monitor.py 30s loop
E11 Telegram推送 server/infrastructure/telegram/__init__.py alert/recovery/system
E12 /health端点 server/api/health.py Shell health_monitor.sh checks this
技术债务
D1 paramiko删除 pool.py已删除, 全部迁移asyncssh
D2 install迁移 server/api/install.py PHP→install.html+API
D3 WebSSH前端 web/app/terminal.html xterm.js+Koko协议+全屏
安全增强
S1 JWT全局保护 server/api/*.py 所有业务API都有JWT验证
S2 审计日志 server/api/*.py 所有CUD操作记录审计日志
S3 登录防暴破 server/application/services/auth_service.py 失败计数+15min锁定+429状态码
前端UX增强
UX1 共享布局 web/app/layout.js 11页面统一侧边栏+全局搜索+用户信息
UX2 Toast通知 web/app/api.js 全局toast()函数,4种类型
UX3 全局搜索 server/api/search.py 跨服务器/脚本/凭据/调度搜索
UX4 服务器详情 web/app/servers.html 点击展开详情面板(系统信息/同步日志/SSH会话)
UX5 脚本编辑 web/app/scripts.html 点击脚本名编辑+执行结果格式化
UX6 推送增强 web/app/push.html 逐服务器状态+进度条+推送历史
UX7 审计分页 web/app/audit.html 分页控件+操作过滤+每页50条
UX8 重试操作 web/app/retries.html 手动重试+删除按钮+状态过滤
UX9 文件浏览 web/app/files.html 面包屑导航+目录排序+父目录链接
UX10 登录安全 web/app/login.html 密码可见切换+失败计数+429锁定+shake动画
P1功能补全
P1-1 资产管理 web/app/assets.html Platform/Node管理页面
P1-2 服务器表单 web/app/servers.html 补全platform/node/protocols字段
P1-3 Push对接 web/app/push.html + sync_v2.py target_path对接+统一SyncEngineV2
P1-4 安全设置 web/app/settings.html TOTP QR码+修改密码+API Key复制
P1-5 WebSSH授权 server/api/webssh.py SSH凭据验证+4003关闭码+审计
P1-6 Agent认证 server/api/agent.py 每服务器API Key + 全局回退
P1-7 Config去重 server/application/services/sync_engine_v2.py sed去重+备份+_rollback_config()
P2安全增强
P2-1 告警防抖 server/api/websocket.py 5分钟冷却+Telegram去重+恢复重置
P2-2 命令日志 web/app/commands.html 命令/会话双视图+服务器过滤+危险命令高亮
P2-3 DB分页 server/infrastructure/database/server_repo.py DB层offset/limit+count
P2-4 Dashboard实时 web/app/index.html WS触发stats刷新+声音+标签页闪烁
P2-5 移动适配 web/app/layout.js <768px侧边栏overlay+backdrop+表格滚动
P2-6 会话安全 server/api/auth_jwt.py + api.js 8小时超时+JWT updated_at+刷新重用检测
P2-7 凭据加密 server/api/servers.py Server.password/ssh_key_private Fernet加密存储
P2-8 凭据脱敏 server/api/scripts.py + servers.py API响应不返回密码,password_set布尔标记
P2-9 DB备份 deploy/db_backup.sh mysqldump+30天保留+cron集成
P3运维增强
P3-1 Nginx重定向 deploy/nginx_https.conf 注释化301规则:裸页面路径→/app/前缀
P3-2 自定义404 server/main.py StarletteHTTPExceptionHandler返回空白HTML,隐藏FastAPI标识

🔄 待测试

  • T1: 心跳Redis写入验证
  • T2: WebSocket连接测试
  • T3: 3层守护测试 (kill Python→Supervisor重启)
  • T4: Telegram推送测试
  • T5: install.html 5步流程测试

测试流程 (用户确认)

  1. WSL本地基础测试 → 2. 推到仓库 → 3. 外网服务器正式测试

配置三写机制

安装向导 Step 3 POST处理同时写入:

  1. web/data/config.json — 共享配置 (API_BASE_URL, DB_*, API_KEY)
  2. .env — Python后端启动必需 (NEXUS_前缀)
  3. settings MySQL表 — 共享动态配置 (api_key, thresholds, Telegram等)

不可改项 (SECRET_KEY/API_KEY/ENCRYPTION_KEY/DATABASE_URL) 不在MySQL覆盖映射中。

3层守护机制

  • Layer 1: Supervisor — Python崩溃自动重启
  • Layer 2: Python self_monitor — 每30s检查Redis/MySQL/WebSocket
  • Layer 3: Shell health_monitor.sh — 每分钟HTTP GET /health, 连续3次失败→supervisorctl restart + Telegram

实现原则(强制 — 见 .cursor/rules/perfect-implementation.mdc

所有设计和实现都必须是完美实现。

  • 不允许为了实现而实现 — 每一行代码必须有明确的目的和质量标准
  • 不允许降级实现 — 不得以「先用着」为由降低安全、架构或代码质量标准
  • 不允许妥协实现 — 不得在发现问题后选择绕过而非根治
  • 不允许留技术债 — 发现问题必须当场修复,不得标注 TODO/FIXME 延后
  • 无法完美实现时必须停下来与用户交流后再换方案,不得擅自从权

文档纪律:

  • 新功能/架构变更:先写 docs/design/specs/YYYY-MM-DD-*-design.md,再写代码
  • 开发前:写 docs/design/plans/docs/reports/ 技术文档(文件清单、步骤、测试、回滚)
  • 项目缺文档的模块:改动时一并补全
  • 每次修改:在 docs/changelog/YYYY-MM-DD-*.md 留 changelog

强制文件修改流程(不可跳步)

实现 → WSL本地验证 → ★审计8步★ → 部署 → 健康检查 → 浏览器验证 → changelog

进度条(每次改代码必须输出,每完成一步打勾):

□实现 □WSL验证 □审计8步 □部署 □健康检查 □浏览器验证 □changelog

用户只需看:没打勾的格子在打勾的格子后面 = 跳步了。 跳步 = 严重过程违规,用户说「你跳步了」必须立即停止并补完。

审计8步(我内部执行,用户不需要检查细节):登记→全文Read→规则扫描H→Closure表→入口表→输入→Sink→归类→DoD 审查4维度30项:安全12+逻辑8+性能5+质量5 三个铁律:每个文件都要审、每行代码都要看、每个结论都要有证据

程序门控 v2(deploy 时自动检查 7 道,不过不让部署):

# 检查内容 防什么
1 Changelog门 文件存在 且行数≥10 空壳changelog
2 Audit门 文件存在 且含 Step3+Closure+DoD 空壳审计
3 Test门 test_api.py 必须存在且通过 删测试绕过
4 Lint门 ruff check server/ 零错误 代码质量问题
5 Import门 import server.main 成功 语法/导入错误
6 Security门 bandit 无 HIGH/MEDIUM 安全反模式
7 Review门 审计文件包含实际改动文件清单 假审查

门控脚本: deploy/pre_deploy_check.sh7门) 门控日志: deploy/gate_log.jsonl(每次检查自动追加记录) MCP deploy 工具在 git pull + restart 前自动执行门控检查,任何一门不过返回 🚫 DEPLOY BLOCKED MCP gate_log 工具可查看历史门控记录 审计模板: docs/audit/TEMPLATE.md Lint配置: ruff.toml 开发依赖: requirements-dev.txtruff, bandit, pytest

部署流程(SSH + SCP,不是 MCP deploy

MCP deploy 不可用GitHub 等 SaaS 的远程服务器 git pull 无凭据),实际部署用 SSH 命令直接操作:

后端部署

# 1. Push 本地到 Gitea
git push origin main

# 2. 服务器拉取最新代码 + 重启
ssh nexus "cd /www/wwwroot/api.synaglobal.vip && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"

# 3. 健康检查
ssh nexus "sleep 3 && curl -s http://127.0.0.1:8600/health"
# 预期: "ok"(纯文本,非 JSON

前端部署(Vuetify SPA

Vite 直接输出到 web/app/(后端 StaticFiles 挂载点),无需 dist 复制步骤:

# 一键部署脚本(构建+打包+上传+提取+重启+验证)
bash deploy/deploy-frontend.sh

# 或手动步骤:
cd frontend && npx vite build && cd ..
tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
scp /tmp/nexus-frontend.tar.gz nexus:/tmp/nexus-frontend.tar.gz
ssh nexus "cd /www/wwwroot/api.synaglobal.vip/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
ssh nexus "supervisorctl restart nexus"

注意: 前端构建产物 (web/app/index.html, web/app/assets/) 已在 .gitignore 中,不进入 git。每次部署需重新构建+上传。

浏览器验证

curl -s -o /dev/null -w "%{http_code}" http://47.254.123.106:8600/app/  # 预期: 200

部署常遇问题

问题 解决
/app/ 返回 404 AppAuthMiddleware 拦截 — 确认 /app//app/index.html_APP_PUBLIC_PATHS
/app/ 返回旧 HTML (Tailwind/Alpine) git reset --hard 恢复了旧文件 — 需要重新 tar+scp 前端构建产物
MCP deploy → git pull 失败 could not read Username 服务器 remote URL 没配 token,用 git remote set-url
Gate 2 Audit BLOCKED 创建 docs/audit/YYYY-MM-DD-topic.md,含 Step3+Closure+DoD
Gate 3 Test BLOCKED (401) 服务器 .env 中 NEXUS_TEST_ADMIN_PASSWORD 与数据库不一致
Gate 6 Security BLOCKED (bandit HIGH) md5 → sha256 等,参看 bandit 报告修复
Gate 7 Review BLOCKED 审计文件缺少实际改动文件清单

部署信息速查

  • 部署用户: root
  • 部署目录: /www/wwwroot/api.synaglobal.vip/
  • Supervisor 服务名: nexus
  • Supervisor 配置: /www/server/panel/plugin/supervisor/etc/supervisor.conf
  • SSH 别名: ssh nexus (47.254.123.106, key: id_rsa_nexus)
  • 后端端口: 8600
  • Gitea Token SHA: 26fee743a9332895b55f79b2dbe2e931dc7c2fe5 (nexus-deploy-token, write:repository)

用户审查清单(验证AI是否偷懒):

  1. deploy/gate_log.jsonl — 每次门控都有记录,没有记录 = 没过门控
  2. 看审计文件 — 必须有 Closure 表(每个H的判定+依据)、Step 3 规则扫描、DoD
  3. 看进度条 — ☑必须在□前面,否则跳步
  4. 看 changelog — 行数≥10,不能是空壳

数据流

Agent心跳(60s) → Redis(实时) → 前端直读 → 10min批量 → MySQL(历史)
告警: CPU/mem/disk > threshold → WebSocket推送浏览器 + Telegram推送手机
恢复: 之前告警的指标恢复正常 → 自动推送恢复通知
Redis心跳key: heartbeat:{server_id} (HSET, TTL=600s)
Redis告警key: alerts:{server_id} (SET, TTL=3600s)