Files
Nexus/docs/release/20260708/Nexus-测试部署机环境修复与验证报告-20260707.md
T
r 9b583ccc91
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / e2e (push) Blocked by required conditions
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
docs(release): 主与 release 分支合并功能清单 + 导入 release 文档目录
便于 Gitea 上 main ↔ release/20260708-axs 合并评审与冲突对照。
2026-07-09 01:14:32 +08:00

8.4 KiB
Raw Blame History

Nexus 测试部署机环境修复与验证报告

生成时间:2026-07-07 06:55Asia/Shanghai

1. 本轮结论

Nexus 局域网测试部署机 192.168.124.219 当前可作为测试部署机使用:

  • Docker 部署正常,Nexus / MySQL / Redis 三个容器均为 healthy。
  • Nexus 健康接口正常:http://127.0.0.1:18600/health 返回 200 OK / ok
  • Web 入口正常:http://192.168.124.219:18600/app/
  • 后端全量 pytest 已通过:727 passed, 1 skipped in 11.75s
  • 前端 type-checkbuild 已通过。
  • 已确认机器已使用国内源,未执行 linuxmirrors.cn 换源脚本,避免重复改源带来风险。

2. 当前部署状态

部署目录:

/opt/nexus-dev-current -> /opt/nexus-dev-20260707-054832

Docker 端口:

服务 容器端口 宿主端口 状态
Nexus 8600 18600 healthy
MySQL 3306 13306 healthy
Redis 6379 16379 healthy

测试机上同时存在宝塔服务,本轮没有修改宝塔文件,也没有重启宝塔:

服务 端口
宝塔面板 29938
宝塔 nginx 80 / 888

3. 国内源与代理状态

已检查到当前测试机已配置国内源:

  • Ubuntu apt:阿里云源。
  • Docker CE:腾讯云源。
  • pip:清华源。
  • npmhttps://registry.npmmirror.com
  • Docker registry mirrorhttps://docker.1ms.run/

Docker daemon 代理已配置为:

HTTP_PROXY=socks5h://127.0.0.1:10808
HTTPS_PROXY=socks5h://127.0.0.1:10808

注意:这个 Docker 代理依赖本机到测试机的 SSH reverse tunnel;如果隧道断开,已存在镜像和容器不受影响,但后续拉新镜像可能失败。

4. 本轮已修复文件

所有上传到远端的文件均先在远端做了 .bak-时间戳 备份。

4.1 之前已上传的环境/测试修复

/opt/nexus-dev-current/pytest.ini
/opt/nexus-dev-current/tests/conftest.py
/opt/nexus-dev-current/tests/test_agent_version.py
/opt/nexus-dev-current/tests/test_agent_heartbeat_stop.py
/opt/nexus-dev-current/tests/test_btpanel_login_url.py
/opt/nexus-dev-current/server/infrastructure/ssh/remote_probe.py
/opt/nexus-dev-current/tests/test_server_connectivity.py

主要修复点:

  1. 新增 pytest.ini,限制 pytest 只收集 tests/,避免误收集 scripts/_browse_test.py
  2. tests/conftest.py 默认把普通测试设置为已安装模式,避免裸跑 pytest 时进入安装模式导致 API 返回 503。
  3. 测试环境缺少 ENCRYPTION_KEY 时注入固定测试 Fernet key,避免测试依赖真实部署 secrets。
  4. Agent 版本测试从旧的 2.0.0 更新为当前代码版本 2.1.1
  5. 宝塔一键登录 URL 单测更新为“不缓存一次性 tmp_token URL”,符合近期长期掉线修复方向。
  6. remote_probe.py 对缺少 psutil 的目标机增加 /proc 降级采集,避免监控命令直接失败。
  7. test_server_connectivity.py 修复 mock 行字段数不足的问题。

4.2 本轮继续上传的链路测试修复

本轮新增上传:

/opt/nexus-dev-current/tests/chain/test_batch_job_flow.py
/opt/nexus-dev-current/tests/chain/test_script_exec_flow.py

远端备份时间戳:

20260707-064723

修复原因:

两个链路测试原来 monkeypatch 了全局 asyncio.create_task,导致 SQLAlchemy / aiosqlite 在测试 teardown 关闭连接时也拿到 MagicMock,最终报错:

TypeError: An asyncio.Future, a coroutine or an awaitable is required
RuntimeWarning: coroutine 'AsyncConnection.close' was never awaited

修复方式:

  • 不再污染全局 asyncio 模块。
  • 只替换业务模块里的 asyncio 引用。
  • _AsyncioProxy 保留其他 asyncio 能力,只拦截业务代码创建后台任务的 create_task()

示意:

class _AsyncioProxy:
    def __getattr__(self, name):
        return getattr(asyncio, name)

    def create_task(self, coro):
        return capture_create_task(coro)

monkeypatch.setattr(
    "server.application.services.server_batch_service.asyncio",
    _AsyncioProxy(),
)

另一个文件同理替换:

monkeypatch.setattr(
    "server.application.services.script_service.asyncio",
    _AsyncioProxy(),
)

5. 验证结果

5.1 本轮 targeted 测试

命令:

cd /opt/nexus-dev-current
. .venv/bin/activate
python -m pytest -q \
  tests/chain/test_batch_job_flow.py::test_batch_category_job_completes_and_persists \
  tests/chain/test_script_exec_flow.py::test_execute_script_reaches_completed

结果:

2 passed in 0.97s

5.2 后端全量 pytest

命令:

cd /opt/nexus-dev-current
. .venv/bin/activate
python -m pytest -q

结果:

727 passed, 1 skipped in 11.75s

5.3 Docker / HTTP 健康检查

检查时间:2026-07-07 06:48:38 +08:00

nexus-mysql-1   Up / healthy   0.0.0.0:13306->3306
nexus-redis-1   Up / healthy   0.0.0.0:16379->6379
nexus-nexus-1   Up / healthy   0.0.0.0:18600->8600

健康接口:

HTTP/1.1 200 OK
ok

Web 入口:

HTTP/1.1 200 OK
/app/

5.4 前端检查

命令:

cd /opt/nexus-dev-current/frontend
npm run type-check -- --pretty false
npm run build

结果:

type-check 通过
build 通过

存在非阻断 warning

  1. :deep(...) CSS 伪类 warning
    • 构建器提示 deep 不是有效 pseudo-class,建议 ::deep
    • 当前不阻断 build,但建议后续统一检查 Vue scoped CSS 写法。
  2. dynamic import warning
    • src/router/index.ts 同时被静态和动态导入,影响拆包效果,不影响功能。
  3. chunk size warning
    • Monaco / Vuetify 相关 bundle 较大,建议后续做按需加载和 chunk 拆分。

6. 宝塔长期掉线问题现状

用户描述的问题是:

不是登录失败,而是一键登录同时打开多个宝塔后,过几个小时陆续掉线,刷新就掉。

当前 Nexus 代码方向已经覆盖了关键点:

  1. 每次一键登录 fresh 生成宝塔 tmp_token。
  2. 不缓存一次性登录 URL。
  3. Redis per-server lock 避免同一服务器并发生成 tmp_token 互相覆盖。
  4. temp login TTL 目标为 86400 秒。

但测试机宝塔本体此前检查到仍可能存在边界风险:

/www/server/panel/data/session_timeout.pl = 86400
/www/server/panel/task.py 仍有 if f_time > 3600:

这意味着即使 session_timeout 设置为 86400,宝塔后台某些清理逻辑仍可能按 3600 秒判断,从而造成几个小时后刷新掉线。

本轮没有修改宝塔本体文件。后续如果要验证/修复,需要明确执行以下步骤:

  1. 备份 /www/server/panel/task.py
  2. 只修改硬编码 session 清理阈值相关逻辑。
  3. 尽量不重启宝塔;如必须重启,先告知影响。
  4. 再做 2 小时以上多窗口一键登录保活测试。

7. 后续建议的代码安全巡检顺序

建议按下面顺序继续做 Nexus 安全巡检:

  1. 配置与 secrets
    • 检查 .env、Docker env、日志输出是否泄露 token/password/key。
    • 检查测试文件是否写入真实密钥。
  2. 认证与授权
    • JWT 登录、安装模式、白名单、管理员接口鉴权。
    • 一键登录宝塔的权限边界与审计日志。
  3. 宝塔一键登录链路
    • tmp_token 生成、并发锁、TTL、错误重试、URL 不缓存策略。
    • 多窗口/多服务器/刷新场景。
  4. SSH 执行链路
    • 命令拼接、参数转义、超时、输出脱敏、失败回滚。
  5. 数据库访问
    • SQLAlchemy 查询是否参数化。
    • 事务边界、异步 session 生命周期。
  6. Redis 缓存/锁
    • key 命名空间、TTL、锁释放、异常路径。
  7. 文件/脚本执行
    • 上传路径限制、脚本内容校验、目录穿越风险。
  8. 前端安全
    • XSS、URL 拼接、iframe/window.open、token 存储位置。
  9. 部署安全
    • Docker 端口暴露、默认密码、CORS、安全响应头、Nginx 代理配置。
  10. 回归测试补齐
  • 为本次发现的安装模式、一次性 URL、asyncio monkeypatch、psutil 降级补长期回归用例。

8. 当前是否还有环境问题

按本轮检查结果:

  • 测试机 Docker 部署没有发现阻断问题。
  • 后端 pytest 没有剩余失败。
  • 前端 type-check/build 没有失败。
  • 仍需关注的是前端 build warning 和宝塔本体 task.py 的 3600 秒清理逻辑。