前言
这次折腾的目标很明确:把 Nexterm 部署到 Hugging Face Spaces,作为一个可以随时打开的 SSH 服务器管理入口。
Nexterm 本身是一个 Web 版服务器管理工具,支持 SSH、SFTP、监控、身份凭据、文件夹分组、Snippets、AI 助手等功能。简单来说,它可以当成一个轻量版的“云端 SSH 管理面板”。
我最后得到的结果是:
- Nexterm 跑在
Hugging Face Docker Space上。 - 数据库使用外部
MySQL,避免 Space 重启后配置丢失。 - SSH 服务器从本地配置文件批量导入。
- 按“工作服务器 / 个人服务器”和服务商做了分组。
- 批量测试哪些服务器能连通。
- 只给个人服务器里可用的机器开启监控,工作服务器不做监控。
这篇文章主要记录过程和踩坑,不会放真实 Token、数据库密码、服务器密码这类敏感信息。

准备
这次用到的东西大概是这些:
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 |
这里最重要的是两点:
- 数据库必须持久化,否则 Space 重启后 Nexterm 里的服务器、身份、分组都会丢。
- 密码、私钥、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 |
3. 处理迁移脚本差异
部署过程中遇到过迁移脚本和 MySQL 语法不兼容的问题,尤其是部分主键、JSON 字段和排序字段相关迁移。
处理方式是:
- 保留 Nexterm 原有迁移体系。
- 只覆盖有 MySQL 兼容问题的迁移。
- 不手工改业务表结构,尽量让迁移 runner 继续负责版本演进。
这一步很重要。如果直接绕开迁移,很容易后续升级时数据库结构对不上。
首次启动与登录
Space 构建成功后,访问 Space 域名即可打开 Nexterm。
首次使用时需要创建账号,然后系统会把会话写入数据库。后续我在自动化测试连接时,也复用了 Nexterm 自己的 API 和会话,而不是直接绕过系统逻辑。
常用入口大概是:
https://<user>-<space>.hf.space |
如果后面接了 Cloudflare 反代,也可以用自己的域名访问。
批量导入 SSH 服务器
服务器来源是本地的 SSH MCP 配置文件。导入时做了几件事:
- 读取每个服务器的名称、地址、端口、用户和认证信息。
- 有密码或私钥的,创建对应的 Nexterm Identity。
- 没有可用凭据的,只创建服务器条目,不绑定身份。
- 按文件夹结构放到对应位置。
最终分组大概是这样:
工作服务器 |
这样做的好处是:服务器数量一多以后,不会全挤在一个列表里。按“用途 + 服务商”分组,后面查找和维护都会轻松很多。

连接测试
导入以后不能直接默认全开监控,因为很多服务器可能存在这些情况:
- 没有绑定可用身份。
- 密码或私钥失效。
- SSH 端口不通。
- 服务器只在内网可访问。
- 从 Hugging Face 出口网络无法访问。
所以我通过 Nexterm 自己的执行命令 API 做了批量测试。测试命令很简单:
echo NEXTERM_OK |
逻辑是:
- 读取 Nexterm 数据库里的服务器条目和默认身份。
- 对每台 SSH 服务器调用 Nexterm 的远程命令执行接口。
- 如果输出包含
NEXTERM_OK,认为这台服务器可用。 - 成功的才允许开启监控。
- 失败或缺凭据的保持关闭。
这个测试方式比单纯 ping 或 TCP 探测更可靠,因为它验证的是完整链路:
Nexterm Web API |
监控策略
一开始测试后,有一批服务器能正常执行命令。后来我决定把“工作服务器”的监控全部关闭,只保留个人服务器里可用的监控。
原因很简单:
- 工作服务器通常不应该被非正式工具频繁探测。
- 有些工作机器的监控应该走公司已有体系,而不是个人面板。
- 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 管理入口已经够用。
后续如果继续完善,我会优先考虑三件事:
- 给 Space 接自定义域名。
- 把常用命令沉淀到 Nexterm Snippets。
- 给真正需要观察的个人服务器补充更清晰的监控面板。