抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前言

这次折腾的目标很明确:把 Nexterm 部署到 Hugging Face Spaces,作为一个可以随时打开的 SSH 服务器管理入口。

Nexterm 本身是一个 Web 版服务器管理工具,支持 SSH、SFTP、监控、身份凭据、文件夹分组、Snippets、AI 助手等功能。简单来说,它可以当成一个轻量版的“云端 SSH 管理面板”。

我最后得到的结果是:

  • Nexterm 跑在 Hugging Face Docker Space 上。
  • 数据库使用外部 MySQL,避免 Space 重启后配置丢失。
  • SSH 服务器从本地配置文件批量导入。
  • 按“工作服务器 / 个人服务器”和服务商做了分组。
  • 批量测试哪些服务器能连通。
  • 只给个人服务器里可用的机器开启监控,工作服务器不做监控。

这篇文章主要记录过程和踩坑,不会放真实 Token、数据库密码、服务器密码这类敏感信息。

海灵把分散服务器收进 Nexterm 云端工具箱

准备

这次用到的东西大概是这些:

  • Hugging Face CLI:用于登录和部署 Space。
  • Hugging Face Docker Space:运行 Nexterm。
  • Aiven MySQL:作为外部数据库。
  • Nexterm 源码:来自 gnmyt/Nexterm
  • 一个本地 SSH 配置文件:用于批量导入服务器。

外部数据库连接字符串不要写进仓库。正确做法是放到 Space 的 Secrets 或环境变量里,例如:

DATABASE_URL=mysql://<user>:<password>@<host>:<port>/<database>?ssl-mode=REQUIRED
ENCRYPTION_KEY=<random-secret>

这里最重要的是两点:

  1. 数据库必须持久化,否则 Space 重启后 Nexterm 里的服务器、身份、分组都会丢。
  2. 密码、私钥、Token 只能放在 Secrets 里,不要放进 Dockerfile 或公开仓库。

为什么需要外部 MySQL

Hugging Face Space 的免费容器适合跑轻量服务,但它不是一台传统 VPS。容器重启、重建、休眠唤醒时,本地文件并不适合作为长期状态保存位置。

Nexterm 需要保存这些数据:

  • 用户和会话。
  • 服务器条目。
  • 文件夹结构。
  • 身份凭据。
  • 监控开关和监控数据。
  • Snippets、脚本和 AI 设置。

所以数据库必须放到外部。这里使用的是 MySQL,本质上是把 Space 当成无状态 Web 服务,把状态交给托管数据库保存。

Docker Space 改造

Nexterm 原项目默认更偏普通 Docker / 自托管场景。为了跑在 HF Space 上,我做了几处适配。

1. 安装 MySQL 驱动

Nexterm 需要能连接 MySQL,所以构建时安装 mysql2

RUN npm install mysql2

2. 覆盖数据库初始化逻辑

原项目数据库层在 MySQL 场景下有一些兼容性问题,所以我在 Space 仓库里覆盖了数据库连接相关文件,让它能正确读取外部 MySQL 连接信息,并启用 SSL。

这里的关键不是写死数据库地址,而是让代码从环境变量读取:

DB_TYPE=mysql
DATABASE_URL=<your-mysql-connection-string>

3. 处理迁移脚本差异

部署过程中遇到过迁移脚本和 MySQL 语法不兼容的问题,尤其是部分主键、JSON 字段和排序字段相关迁移。

处理方式是:

  • 保留 Nexterm 原有迁移体系。
  • 只覆盖有 MySQL 兼容问题的迁移。
  • 不手工改业务表结构,尽量让迁移 runner 继续负责版本演进。

这一步很重要。如果直接绕开迁移,很容易后续升级时数据库结构对不上。

首次启动与登录

Space 构建成功后,访问 Space 域名即可打开 Nexterm。

首次使用时需要创建账号,然后系统会把会话写入数据库。后续我在自动化测试连接时,也复用了 Nexterm 自己的 API 和会话,而不是直接绕过系统逻辑。

常用入口大概是:

https://<user>-<space>.hf.space

如果后面接了 Cloudflare 反代,也可以用自己的域名访问。

批量导入 SSH 服务器

服务器来源是本地的 SSH MCP 配置文件。导入时做了几件事:

  1. 读取每个服务器的名称、地址、端口、用户和认证信息。
  2. 有密码或私钥的,创建对应的 Nexterm Identity。
  3. 没有可用凭据的,只创建服务器条目,不绑定身份。
  4. 按文件夹结构放到对应位置。

最终分组大概是这样:

工作服务器
├─ 阿里云
├─ 阿里云国际
├─ 腾讯云
└─ 其他云厂商

个人服务器
├─ 阿里云
├─ Oracle Cloud
├─ 百度智能云
├─ Serv00
├─ 本地网络
└─ Hugging Face

这样做的好处是:服务器数量一多以后,不会全挤在一个列表里。按“用途 + 服务商”分组,后面查找和维护都会轻松很多。

海灵用抽屉把工作和个人服务器分组整理

连接测试

导入以后不能直接默认全开监控,因为很多服务器可能存在这些情况:

  • 没有绑定可用身份。
  • 密码或私钥失效。
  • SSH 端口不通。
  • 服务器只在内网可访问。
  • 从 Hugging Face 出口网络无法访问。

所以我通过 Nexterm 自己的执行命令 API 做了批量测试。测试命令很简单:

echo NEXTERM_OK

逻辑是:

  1. 读取 Nexterm 数据库里的服务器条目和默认身份。
  2. 对每台 SSH 服务器调用 Nexterm 的远程命令执行接口。
  3. 如果输出包含 NEXTERM_OK,认为这台服务器可用。
  4. 成功的才允许开启监控。
  5. 失败或缺凭据的保持关闭。

这个测试方式比单纯 ping 或 TCP 探测更可靠,因为它验证的是完整链路:

Nexterm Web API
-> Nexterm Engine
-> SSH 认证
-> 远程 shell 执行
-> 返回 stdout

监控策略

一开始测试后,有一批服务器能正常执行命令。后来我决定把“工作服务器”的监控全部关闭,只保留个人服务器里可用的监控。

原因很简单:

  • 工作服务器通常不应该被非正式工具频繁探测。
  • 有些工作机器的监控应该走公司已有体系,而不是个人面板。
  • Nexterm 部署在 HF Space 上,监控请求来自外部网络,容易产生误判或审计噪音。
  • 个人服务器更适合用这个面板做轻量状态观察。

最后保留监控的是个人服务器里可连通的几台,工作服务器全部关闭。

海灵把工作服务器监控开关拨到关闭

遇到的问题

MySQL 兼容问题

Nexterm 默认迁移在不同数据库上不一定完全一致。遇到问题时不要急着手工建表,优先看迁移脚本和 ORM 生成的 SQL。

这次主要处理的是:

  • MySQL 驱动缺失。
  • 迁移脚本不兼容。
  • JSON 字段在 MySQL 下的读写问题。

凭据缺失

有些服务器配置里没有密码,也没有可用私钥。这类条目可以先导入,但不能测试连接,也不能开监控。

后面要么在 Nexterm 里手动补 Identity,要么重新从源配置导入凭据。

内网服务器不可达

像路由器、树莓派这类本地网络设备,从 Hugging Face Space 访问不到是正常的。

这不是 Nexterm 配错了,而是网络位置不对。HF Space 在公网云端,本地 192.168.x.x 或内网地址对它没有意义。

不要把监控全开

监控不是越多越好。尤其是 SSH 监控,会涉及认证、命令执行、日志记录和网络访问。

我的建议是:

  • 个人服务器可以按需开启。
  • 工作服务器默认关闭。
  • 缺凭据、认证失败、内网不可达的不要开。
  • 如果后续要正式监控,应该接入更合适的监控系统。

总结

这次部署的核心思路是:HF Space 跑服务,外部 MySQL 存状态,Nexterm 管连接,监控只开必要部分

它不适合替代完整堡垒机,也不适合承载公司级监控体系,但作为个人使用的轻量 SSH 管理入口已经够用。

后续如果继续完善,我会优先考虑三件事:

  1. 给 Space 接自定义域名。
  2. 把常用命令沉淀到 Nexterm Snippets。
  3. 给真正需要观察的个人服务器补充更清晰的监控面板。

评论




站点访问量 Loading… 站点访客数 Loading…