/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
在 Armbian 上零成本搭建手机可访问的远程桌面(Xvfb + XFCE + noVNC + nps 全流程)
硬件只是一块吃灰的 ARM 板子(Armbian 系统),没有显示器、没有键鼠,全程 SSH 操作。最终效果:手机浏览器打开一个网址,就能看到完整的 Linux 桌面并操作 Chromium,断线自动恢复、开机自启。以下是踩坑之后的完整复盘。
一、整体架构
先看清楚整条链路,每一环各司其职,出问题时按图索骥:
手机浏览器
│ HTTP
▼
nps 服务端(公网穿透)
│ TCP 隧道 → 127.0.0.1:6080
▼
websockify(WebSocket ⇄ VNC 转换,附带 noVNC 网页)
│ VNC 协议(localhost:5900)
▼
x11vnc(捕获 X 显示器的画面并转发)
│ 读取 :99
▼
Xvfb(虚拟显示器,1280×720,无需真实屏幕)
│
▼
XFCE 桌面 + Chromium(真正跑在虚拟屏幕上的东西)
一句话概括:Xvfb 造出一块“看不见的屏幕”,XFCE 和 Chromium 在上面运行,x11vnc 把屏幕画面变成 VNC 流,websockify 把 VNC 流变成网页,nps 把网页送到公网。
二、安装软件
sudo apt update
sudo apt install -y xvfb x11vnc novnc dbus-x11 chromium supervisor
各包的作用:
| xvfb | 虚拟显示器 |
| x11vnc | 把 X 显示器画面以 VNC 协议输出 |
| novnc | 网页版 VNC 客户端(自带静态页面) |
| dbus-x11 | XFCE 桌面需要的 dbus 会话 |
| chromium | 浏览器本体 |
| supervisor | 进程守护,防断线、防崩溃 |
三、设置 VNC 密码
不要用 -passwd 明文密码 的方式(会留在 shell 历史和 ps aux 里),用密码文件:
x11vnc -storepasswd
按提示输入两遍密码,保存到默认路径 /root/.vnc/passwd。这个密码就是之后手机登录 noVNC 时用的。
四、核心配置:supervisor 托管全部五个进程
为什么不手动 nohup 启动? 我最初的方案是 SSH 里手动起进程,结果手机 SSH 一断(息屏、切后台),所有子进程被连带杀掉,只剩一个孤零零的 Xvfb——这就是“明明刚才还好好的”的根因。用 supervisor 托管后:进程挂了自动拉起、板子重启自动整套恢复。
sudo tee /etc/supervisor/conf.d/novnc-chain.conf > /dev/null <<'EOF'
[program:xvfb]
command=Xvfb :99 -screen 0 1280x720x24
autorestart=true
startsecs=3
priority=5
[program:xfce]
command=/bin/bash -c "sleep 8; exec dbus-launch startxfce4"
environment=DISPLAY=":99",HOME="/root"
autorestart=true
startsecs=15
startretries=10
priority=10
stdout_logfile=/var/log/supervisor/xfce.log
stderr_logfile=/var/log/supervisor/xfce.err
[program:x11vnc]
command=x11vnc -display :99 -rfbauth /root/.vnc/passwd -forever -shared -quiet
autorestart=true
startsecs=5
priority=20
stdout_logfile=/var/log/supervisor/x11vnc.log
stderr_logfile=/var/log/supervisor/x11vnc.err
[program:websockify]
command=websockify –web /usr/share/novnc/ 6080 localhost:5900
autorestart=true
startsecs=5
priority=30
stdout_logfile=/var/log/supervisor/websockify.log
stderr_logfile=/var/log/supervisor/websockify.err
[program:chromium]
command=/bin/bash -c "sleep 10; exec chromium –no-sandbox –user-data-dir=/root/.config/chromium"
environment=DISPLAY=":99",HOME="/root"
autorestart=true
startsecs=15
startretries=10
priority=40
stdout_logfile=/var/log/supervisor/chromium.log
stderr_logfile=/var/log/supervisor/chromium.err
EOF
配置里有几个用血泪换来的细节:
五、启动与验证
sudo systemctl enable –now supervisor
sudo supervisorctl reread
sudo supervisorctl update
sleep 25
sudo supervisorctl status
预期输出五行全 RUNNING:
chromium RUNNING pid xxxx, uptime 0:00:15
x11vnc RUNNING pid xxxx, uptime 0:00:20
websockify RUNNING pid xxxx, uptime 0:00:20
xfce RUNNING pid xxxx, uptime 0:00:15
xvfb RUNNING pid xxxx, uptime 0:00:20
注意一个坑:如果之前有程序进入过 FATAL 状态,修好配置后它不会自动复活,需要手动拉起:
sudo supervisorctl start xfce chromium
端口验证:
ss -tlnp | grep -E "5900|6080"
应看到 5900(x11vnc)和 6080(websockify)各监听一行。
如果有程序反复 FATAL,看独立日志定位:
sudo cat /var/log/supervisor/xfce.err
sudo cat /var/log/supervisor/chromium.err
六、nps 内网穿透
板子在家里的局域网,手机在外网,需要穿透。在 nps 管理界面添加一条 TCP 隧道:
- 服务端端口:任意公网端口(例如 6080)
- 目标地址:127.0.0.1:6080
七、手机访问
手机浏览器打开:
http://nps服务器IP:6080/vnc.html
输入第三节设置的 VNC 密码,应该就能看到 XFCE 桌面和 Chromium 窗口,点击、滑动都有响应——全链路打通。
八、两个体验优化
1. 手机唤不出键盘
noVNC 用 canvas 接管了画面,手机浏览器点桌面不会弹输入法。两个解法:
- 先试 noVNC 自带的:页面左侧边缘有个把手,拉开侧边栏,点键盘图标可以强制唤起输入法;
- 一劳永逸:在虚拟桌面里装一个屏显软键盘,跟 VNC 无关,肯定能用:
sudo apt install -y matchbox-keyboard
sudo tee /etc/supervisor/conf.d/keyboard.conf > /dev/null <<'EOF'
[program:keyboard]
command=/bin/bash -c "sleep 12; exec matchbox-keyboard"
environment=DISPLAY=":99",HOME="/root"
autorestart=true
startsecs=5
EOF
sudo supervisorctl reread
sudo supervisorctl update
之后桌面下方会浮出一个可拖动的软键盘。
2. 中文乱码
乱码不是编码问题,是没装中文字体。两步解决:
sudo apt install -y fonts-noto-cjk fonts-wqy-zenhei
fc-cache -fv
sudo supervisorctl restart xfce chromium
装完刷新 noVNC 页面,界面和网页的中文都正常了。系统 locale 保持默认英文即可,不要改成中文,SSH 排障时输出更干净。
九、日常运维速查
sudo supervisorctl status # 查看五个进程状态
sudo supervisorctl restart all # 全部重启
sudo supervisorctl start xfce # 单独拉起某个 FATAL 的程序
sudo reboot # 重启后整套自动恢复,无需任何操作
十、踩坑总结
| SSH 断线全挂 | 过会儿进程消失 | 进程挂在 SSH 会话下,用 supervisor 托管 |
| xfce/chromium FATAL | 反复退出进 FATAL | 比 Xvfb 先启动,加 sleep + priority 排序 |
| 修复后不自动恢复 | 配置对了还是 FATAL | supervisor 的 FATAL 不会自愈,手动 start |
| Chromium 起不来 | 退出码 1 | root 需要 –no-sandbox –user-data-dir |
| 界面中文乱码 | 方块/问号 | 缺字体,装 fonts-noto-cjk |
| 手机打不出字 | 点屏幕无输入法 | canvas 劫持键盘,用侧边栏键盘或 matchbox-keyboard |
结语
整套方案的总成本几乎为零:一块吃灰的板子 + 已有的 nps 服务器。它可以直接当“随身 Linux 桌面”用——跑挂机脚本、临时登录某些只能在桌面环境使用的服务、或者纯粹当远程浏览器。 supervisor 托管之后,我已经两周没碰过它了,它就那么安静地跑着。
有问题欢迎评论区交流。
网硕互联帮助中心






评论前必须登录!
注册