跳转到内容

执行 apt upgrade 之后无法登录、打不开管理界面

典型经过是这样的:开启 SSH,登录进去,看到熟悉的 Debian 提示符,顺手敲了一句 apt update && apt full-upgrade。命令跑完,SSH 断开——然后网页管理界面再也打不开了,手机 App 也登录不上。

这是 fnOS 上最常见的一类自损事故。本页说明它为什么会发生、能不能救,以及怎么避免。

先停下来,不要做这三件事

不要重装系统——在确认清楚之前,重装可能让你失去本来能救回来的配置。 不要格式化任何硬盘,也不要对存储空间做任何操作。 不要凭搜索到的命令随手往下敲——特别是带 rmddmkfs 的命令。

好消息是:这类故障通常只破坏了系统盘上的软件环境,数据盘上的文件多半完好。你的目标是在不碰数据的前提下恢复系统。

为什么会这样

fnOS 的底座是 Debian,但它不是一个普通的 Debian 系统

官方源里的系统组件是配套发布的:管理界面、授权服务、数据库、Web 服务器、内核,这些东西的版本经过一起测试,彼此之间有明确的依赖关系。

apt upgrade 做的事情是:把系统里所有能升级的包,升级到上游 Debian 仓库里的最新版本。这会撞上几类问题:

被替换的东西后果
PostgreSQLfnOS 的授权等服务连不上数据库,管理界面返回 502 或「系统内部错误」
nginx 等 Web 组件管理界面端口不再监听,浏览器直接连不上
systemd、glibc 等基础库多个 fnOS 服务启动失败,症状五花八门
内核最严重——存储相关模块不匹配,可能开不了机,或者开机了但存储空间挂不上

所以「无法登录」和「打不开管理界面」往往不是同一个原因,而是多个服务同时挂掉的综合表现。

这也是升级 fnOS 本身会失败的原因

手动动过底层环境的系统,在之后执行 fnOS 官方版本更新时也容易失败。飞牛官方论坛有专门的更新失败问题处理合集,其中包含修复脚本,见下方参考资料(需要论坛账号访问)。

第一步:判断故障到哪一层

按这个顺序确认,每一步的答案决定下一步做什么。

机器还能开机吗

接上显示器和键盘,看能不能进到系统的本地控制台。

  • 能进 → 系统内核和基础启动流程还在,多半只是服务层面的问题,继续往下。
  • 黑屏或卡在引导 → 内核可能被换掉了,这种情况自行修复的难度很高,直接跳到什么时候该重装

SSH 还能连上吗

sh
ssh 你的用户名@NAS地址
  • 能连 → 这是最好的情况,你有完整的排查手段。
  • 连不上但能开机 → 用本地控制台(接显示器键盘)操作,下面的命令同样适用。

网页界面是哪种打不开

这两种表现指向不同的方向:

现象含义
浏览器提示无法连接 / 连接被拒绝Web 服务没在监听,端口是空的
页面能打开但卡在登录页,或提示 502、「系统内部错误」Web 服务活着,但它依赖的后端服务挂了

第二种反而更容易修——说明系统大体健康,只是某个服务没起来。

第二步:找出哪些服务挂了

登录后先看全局:

sh
systemctl --failed

这条命令列出所有启动失败的服务单元。这是整个排查里信息量最大的一条命令,先看它,再做任何猜测。

然后看具体服务的状态:

sh
systemctl status postgresql
systemctl status nginx

以及端口有没有在监听:

sh
ss -tlnp

-t 只看 TCP、-l 只看监听状态、-n 不解析域名、-p 显示对应进程。管理界面的端口如果不在列表里,说明服务确实没起来。

再看日志:

sh
journalctl -p err -b | tail -50
journalctl -xeu 服务名 --no-pager | tail -30

-p err 按错误级别过滤,-b 限定本次启动;第二条看某个具体服务的详细日志。日志里几乎总会写清楚它为什么起不来,比如缺少某个库、配置文件格式不认识、或者端口被占用。

一个真实案例:数据库端口被占用

社区里有一个被反复引用的排查记录,症状是登录页卡住、浏览器控制台显示授权相关请求返回 502,根源是授权服务依赖的 PostgreSQL 没能启动——数据库端口被一个残留进程占着。

排查过程大致是这样(命令来自该记录,版本号和端口以你实际看到的为准):

sh
pg_lsclusters                       # 查看数据库集群状态,down 表示没跑起来
pg_ctlcluster 15 main start         # 尝试启动,看它报什么错
journalctl -xeu postgresql@15-main.service --no-pager | tail -30

如果日志里出现类似 could not bind ... Address already in use,说明端口被占用:

sh
ss -tulnp | grep :5432              # 找出占用 5432 端口的进程和 PID

结束进程和删除文件之前,先看清楚

后续步骤涉及强制结束进程和删除 PID 文件。动手之前确认你看到的进程确实是残留的数据库进程,而不是正在正常工作的其他服务。

kill -9 是强制终止,不给进程保存数据的机会。对数据库执行它,有造成数据损坏的可能。只在进程已经卡死、常规方式停不掉时才用,并且先确认这个数据库里的内容有没有备份。

删除 PID 文件同理:删错文件可能让服务的状态更混乱。每一条命令执行前,先读懂它操作的是哪个路径。

确认无误后,清理残留并重新启动集群,再启动依赖它的服务,最后确认这些服务设置了开机自启——否则重启一次问题就会复现。

这是社区方案,不是官方修复步骤。 你的版本号、服务名和实际原因都可能不同,把它当作「排查思路的示例」,而不是照抄的脚本。

第三步:能不能自己修好

到这里做个判断:

情况建议
只有一两个服务失败,日志里原因明确值得尝试修复
systemctl --failed 列出一长串修复的性价比很低,考虑重装
内核被替换、开不了机直接重装
你已经折腾了两小时还没缩小范围停手,走重装

修复的目标不是「修好」,而是「进得去」

如果你能让管理界面重新打开,第一件事不是继续修,而是:把配置导出、把重要数据确认一遍、把容器的 compose 文件备份走。拿到这些东西之后,重装是一个轻松的选项。

什么时候该重装

出现下列任一情况,重装比继续修划算:

  • 内核被替换,系统起不来。
  • 大量服务启动失败,日志指向基础库版本不匹配。
  • 你不确定自己之前还动过什么。

重装之前必须做的事

重装会清空系统盘

安装程序会重建目标盘的分区。最稳妥的做法是:断电,把所有数据盘的数据线拔掉,只留系统盘,装完再把数据盘接回去。

这比在安装界面里靠型号辨认要可靠得多——辨认错一次,代价是全部数据。

顺序是这样:

  1. 如果还能进系统,先把配置和 compose 文件导出备份
  2. 确认重要数据在别处还有一份,见3-2-1 原则
  3. 断电,拔掉数据盘的数据线。
  4. 安装 fnOS重装到系统盘。
  5. 关机,把数据盘接回去,开机。
  6. 让系统识别已有的存储空间。
  7. 重建共享文件夹权限、容器和定时任务。

官方也提供了系统恢复相关的功能,见下方参考资料,可以在重装之前先了解一下它能做到什么程度。

重装之后

把这次的经历变成两件事:

  • 记录下你的配置:存储空间结构、共享文件夹与权限、容器 compose 文件、定时任务。下次重建时它能省掉几天,见开发者工作流里用 Git 管理 compose 的做法。
  • 检查备份是不是真的可用,见恢复演练。这次没丢数据是运气好,不是体系可靠。

怎么避免再次发生

记住这条边界

操作结论
查看状态、读日志、排查问题放心用命令行
apt install 装个 htop 之类的小工具一般可以,但要接受系统升级后可能失效
apt upgrade / apt full-upgrade不要
apt 升级内核、systemd、数据库等基础组件不要
直接改存储、共享、用户的底层配置不要,用网页端

完整讨论见SSH 与命令行

需要装东西时,优先用容器

想跑一个服务、试一个工具,用容器而不是往宿主机上装。容器有自己的依赖环境,装坏了删掉重来,不会影响系统本身。这是自托管场景下最重要的一条习惯,见Docker 入门

系统更新走官方渠道

fnOS 自身的版本更新在网页端完成,那是经过配套测试的。apt 拉来的是 Debian 上游的版本,两者不是一回事。

动手之前留一条退路

在做任何底层改动之前:

  • 导出一份系统配置。
  • 把容器的 compose 文件备份走。
  • 如果存储空间是 Btrfs,确认快照策略在跑。

延伸阅读

参考资料

fnOS 非官方中文使用指南,与飞牛官方无隶属关系。