我把闲置的斐讯 N1 改成了家庭服务器

wl 发布于 4 天前 12 次阅读 折腾记录


AI 摘要

当初花一百块买的斐讯 N1,在角落吃灰多年。一次偶然的想法,让它重新通电,并最终跑起 8 个 Docker 容器,从智能聊天到服务监控,变成我的家庭服务器。它是怎样被一步步“唤醒”的?

这台斐讯 N1【1】 是我很久以前在拼多多买的,带原装电源大约一百元。

买来后,我把它刷成了软路由【2】,用来做 VPN 代理。N1 有千兆网口【3】,功耗也低,放在家里长期通电没有什么负担。

实际用了没多久,我还是回到了原来的习惯。电脑和手机上各自安装代理软件【4】,切换节点、修改规则、临时开关都更方便。软路由上的代理逐渐用得少了,N1 也被断电收了起来。

后来我看到了 AstrBot【5】

AstrBot 可以接入 QQ,再调用大模型【6】生成回复,还能通过插件【7】增加各种功能。我不想为了一个 QQ 机器人一直开着电脑,便想起了那台闲置的 N1。

我重新给它接上电源,安装 Armbian【8】,准备让它长期运行 AstrBot。

从 AstrBot 开始

安装 Armbian 后,我通过 SSH【9】 管理 N1,并在上面部署 Docker【10】

N1 的内置 eMMC【11】 只有 8GB。系统安装完成后,继续把 Docker 镜像和容器数据放在根分区里,很快就会遇到空间问题。

我接入了一块杂牌 8GB U 盘,格式化为 ext4【12】,挂载到:

/mnt/data

Docker 和 containerd【13】 的数据目录也迁到了这块盘里。系统继续留在 eMMC,镜像、容器和持久化数据都放在 /mnt/data

AstrBot 本身负责机器人逻辑和模型调用,QQ 接入交给 NapCat【14】。两者都运行在 Docker 中,通过 OneBot v11【15】 反向 WebSocket 连接:

ws://astrbot:6199/ws

这里的 astrbot 是 Docker Compose【16】 中的服务名。NapCat 和 AstrBot 位于两个容器中,NapCat 容器里的 127.0.0.1 只会指向 NapCat 自己,连接另一个容器需要使用 Docker 网络中的服务名。

配置完成后,我在 QQ 中发送消息,AstrBot 能够收到,模型生成的内容也能通过 NapCat 返回 QQ。

N1 重新开机后的第一个用途,就这样确定了下来。

随后我安装了 Portainer【17】,用网页管理 Docker;又安装了 Glances【18】,用来查看 CPU、内存、Swap【19】、磁盘和温度。

N1 的内存大约只有 2GB。我给系统增加了 Swap,把 swappiness 调整为 10,也限制了系统日志的最大占用,避免日志长期增长后挤满 eMMC。

散热方面,我接了一个普通 USB 风扇。没接风扇时,温度大约在 53℃;接上后降到了 39℃左右,之后通常维持在 40℃上下。

第一块数据盘很快满了

那块杂牌 8GB U 盘在系统中实际可用约 7.3GB。

AstrBot、NapCat 和 Portainer运行一段时间后,Docker 镜像、容器层和持久化数据已经占用了 5GB 多,剩余空间只剩一两 GB。

继续使用并不会立即出问题,但已经不适合再增加服务。Docker 所在的磁盘一旦写满,镜像拉取、日志写入和程序保存配置都有可能失败。

我手里有一块一直在用的 64GB Kingston U 盘,便先拿来给 N1 过渡。

这块盘原本有自己的用途,我之后还要继续使用。当时没有准备其他存储设备,只能先解决 N1 空间不足的问题。

我把 64GB U 盘接入 N1,临时挂载到 /mnt/newdata,再将原来 /mnt/data 中的内容复制过去。复制完成后,新盘接管 /mnt/data,Docker 的数据路径保持不变。

挂载配置使用 UUID【20】,没有直接写 /dev/sda1。USB 设备的盘符会受到接口和识别顺序影响,换一个接口后,原来的 /dev/sda1 可能会变成 /dev/sdb1,UUID 则不会跟着变化。

换盘后,Docker、Portainer、AstrBot、NapCat 和 Glances 都能正常启动。数据盘的可用空间也从一两 GB 增加到了四十多 GB。

随后,AstrBot 的插件状态出现了异常。

插件开关无法保存

在 AstrBot 的 WebUI 中启用插件后,日志能够看到启用操作。刷新页面或者重启容器,插件又会恢复成未启用状态。

我先检查了当时安装的插件。

mnemosyne 存在明确的依赖冲突。插件要求的 psutil 版本低于 AstrBot 当前环境使用的版本,继续安装可能影响 AstrBot 的核心依赖。

qzoneqzone_ultra 同时存在,注册了大量相同指令。

另一个插件目录被改成了:

antipromptinjector.disabled

我原本以为增加 .disabled 后缀后,AstrBot 就不会继续加载。实际运行时,它仍然会扫描 plugins 目录中的子目录。最后只能把这个目录移到 plugins 之外。

这些插件问题逐个处理后,启用状态仍然无法保存。

我测试了 /AstrBot/data 的写入权限,文件可以正常创建和删除。数据目录中还有数据库、WAL【21】plugins.json 和其他插件配置。

当时的排查方向开始转向旧数据本身。数据库、WAL 或插件配置之间可能存在状态不一致,但现有日志没有明确记录 SQLite 文件损坏,也没有足够的检查结果能够确认根因。

我能够确定的现象只有一个:迁移后的旧 AstrBot 环境无法可靠保存插件状态。

继续排查需要同时处理数据库、插件残留和依赖冲突。我停止了 AstrBot 和 NapCat,删除旧容器、旧 Docker 网络和原来的项目目录,重新创建了一套环境。

重装时盖掉了 NapCat 的启动文件

AstrBot 重新启动得很顺利,NapCat 却一直报错:

bash: entrypoint.sh: No such file or directory

我检查 Compose 配置时发现,自己给 NapCat 添加了这一项:

volumes:
  - ./napcat_data:/app

宿主机上的 napcat_data 是一个空目录。它被挂载到容器的 /app 后,镜像原本放在 /app 中的文件全部被遮住,NapCat 启动时自然找不到 entrypoint.sh

删掉这项挂载后,NapCat恢复运行。

NapCat 重装后需要重新扫码登录 QQ。登录完成后,我再次配置了到 AstrBot 的 WebSocket 连接。

启动过程中,NapCat 日志出现过连接拒绝。继续查看 AstrBot 日志后发现,AstrBot 当时还没有完成启动,6199 端口尚未开始监听。

过了一会儿,NapCat 自动重连,AstrBot 日志中出现了 /ws 连接成功和 OneBot v11 适配器已连接的记录。

我在 QQ 中发出测试消息,AstrBot 能够收到,机器人也重新恢复了回复。

旧插件没有一次性装回去。每次只安装一个,重启 AstrBot,查看日志,再确认插件启用状态是否能够保留。

服务慢慢多了起来

AstrBot 和 NapCat 稳定后,我又部署了 SillyTavern【22】

SillyTavern 的配置和数据放在:

/mnt/data/sillytavern

第一次从电脑访问时,页面返回 403。查看日志后,发现电脑的局域网地址不在白名单【23】中。

我尝试过关闭白名单,SillyTavern 在监听局域网地址、又没有其他认证保护时会触发安全检查。最后仍然保留白名单,只加入需要访问的几台设备。

当时 N1 上已经有 AstrBot、NapCat、SillyTavern 和 Portainer。每个服务都有单独的端口,排查问题时还要登录 SSH 查看容器日志。

我在 /mnt/data/docker/n1-tools 中又部署了四个工具:

Homepage
Uptime Kuma
File Browser
Dozzle

Homepage【24】 用来集中放置服务入口。以前需要记住各个端口,后来先打开 Homepage,就能进入 AstrBot、NapCat、SillyTavern、Portainer 和其他页面。

Uptime Kuma【25】 定时检查服务是否在线。能正常返回网页的服务使用 HTTP 检测,只提供端口的服务则使用 TCP 检测。

Dozzle【26】 用来查看 Docker 日志。机器人没有回复时,可以直接查看 AstrBot 和 NapCat;其他服务启动失败,也能在页面中找到对应容器的输出。

File Browser【27】 负责查看和下载数据盘中的文件。

它第一次启动时,读取到了一个空的 settings.json,日志提示 JSON 解析失败。删除这个空文件后,第二次启动又因为数据库文件权限不足而失败。调整目录和数据库文件权限后,File Browser 才正常完成初始化。

File Browser 映射了整个 /mnt/data。Docker、SillyTavern 和备份目录都能直接看到,运行中的目录也不能随意移动或删除。

到这时,N1 上已经有 8 个 Docker 容器:

astrbot
napcat
sillytavern
portainer
uptime-kuma
dozzle
filebrowser
homepage

原来的 1GB Swap 也已经使用了不少。我没有关闭原 Swap,而是另外增加了一个 1GB Swap 文件,总容量变成 2GB。

服务数量没有再继续增加。

给 N1 买一块长期使用的数据盘

64GB Kingston 在 N1 上运行了一段时间后,我买了一块新的 32GB SanDisk U 盘。

之前的 64GB U 盘只是临时借给 N1 使用,我自己还要拿回来。新的 32GB U 盘专门留给 N1,长期挂载在 /mnt/data

当时数据盘中实际使用约 15GB,32GB 的容量足够容纳。

这次迁移前,我先停止 Docker、Docker Socket【28】 和 containerd。检查系统时,仍然能看到 containerd-shim-runc-v2 进程和 overlay【29】 挂载,说明部分容器文件系统还在使用 /mnt/data

我重新启动 Docker,先通过 Docker 正常停止所有容器,再停止 Docker、Socket 和 containerd。确认相关进程和 overlay 挂载全部消失后,才开始复制。

新 U 盘出厂时是 FAT32【30】。Docker 数据中包含 Linux 权限、属主、软链接、ACL【31】 和扩展属性【32】,我把它重新格式化为 ext4,再挂载到 /mnt/newdata

数据复制完成后,两块盘的文件数量都是:

342399

两边显示的已用空间相差几百 MB。不同 ext4 文件系统的块分配、inode【33】 和稀疏文件【34】占用会产生差异,只看容量无法判断文件是否缺失。

我又使用校验模式检查了一遍,命令没有输出。

随后修改 /etc/fstab,让新盘的 UUID 接管 /mnt/data。Docker Root Dir【35】、容器配置和持久化数据全部保留。

第一次启动 Docker 时,只有 Portainer 自动运行。Portainer 使用 always 重启策略,其他容器大多使用 unless-stopped

迁移前,我手动停止过这些容器。Docker 保留了人工停止状态,因此它们没有自动恢复。手动启动后,8 个容器全部运行,File Browser、Uptime Kuma 和 Homepage 的健康检查【36】也通过了。

确认新盘运行正常后,我关闭 N1,拔掉 64GB U 盘,再把新的 32GB U 盘插到原来的 USB 接口。

重新开机后,新盘的设备名从 /dev/sdb1 变成了 /dev/sda1。系统仍然按照 UUID 将它挂载到 /mnt/data,Docker 和容器数据没有受到影响。

64GB U 盘也终于可以拿回来继续使用。

从 Wi-Fi 换回网线

N1 早期接过网线,后来因为摆放位置改用了 Wi-Fi。无线地址为 192.168.x.17,一段时间内,各个服务都通过这个地址访问。

数据盘和容器稳定后,我重新接上网线。

接线后,系统同时保留了有线和无线连接。有线连接的路由优先级更高,外网流量已经通过 eth0 传输。

网卡状态显示:

Speed: 1000Mb/s
Duplex: Full
Link detected: yes

我在 N1 上运行 iperf3【37】,使用 Windows 电脑进行双向测试。

Windows 到 N1 约为 941Mbps,N1 到 Windows 约为 946Mbps,TCP 重传为 0。外网下载约为 938 至 946Mbps,上传约为 38Mbps。

个别测速节点会超时,或者返回明显异常的下载结果。更换节点后,速度恢复正常。

有线连接通过测试后,我关闭了无线自动连接。路由器按照 N1 有线网卡的 MAC 固定分配 192.168.x.91,N1 内部继续使用 DHCP【38】

Homepage 和 Uptime Kuma 中仍然保存着旧的无线地址。

我先备份 Homepage 配置,再把服务入口统一改成新的有线地址。Uptime Kuma 的监控项则通过网页逐个修改。

修改完成后,我重启了 N1。

重新连接时,有线地址正常,无线保持断开,Docker、containerd 和 8 个容器全部恢复运行。Homepage、Uptime Kuma 和 File Browser 的健康检查也都通过了。

现在的 N1

目前 N1 上运行着 8 个 Docker 容器:

portainer
sillytavern
astrbot
napcat
homepage
uptime-kuma
filebrowser
dozzle

系统中还有 SSH、Docker、containerd 和 Glances Web。

Armbian 和系统服务运行在 eMMC 中,Docker 与业务数据存放在 32GB U 盘的 /mnt/data 中。有线网络作为日常连接,无线配置仍然保留,但不会自动连接。

平时我会先打开 Homepage,再进入需要的服务。Uptime Kuma 记录在线状态,Dozzle 查看容器日志,File Browser 用来下载文件和备份,Glances 显示温度、内存和磁盘,Portainer负责管理 Docker。

当初因为 AstrBot,我重新给这台闲置的 N1 接上了电源。

现在它运行着 8 个 Docker 容器,长期留在家里的局域网中。

最后更新于 2026-07-12