
1. 项目概述为什么在 Ubuntu 20.04 上用 NoMachine 必须配虚拟桌面NoMachine 是我用过最稳的远程桌面工具之一尤其在低带宽、高延迟或需要传输 OpenGL 图形比如跑 ROS 的 rviz、OpenCV 的 imshow、Blender 渲染预览的场景下它比 VNC 流畅得多也比 RDP 更轻量。但很多人装完 NoMachine一连就报错“No session available”、“Connection failed: no desktop environment found”或者连上了却只有黑屏、鼠标能动但桌面不渲染——这几乎 90% 都是因为 Ubuntu 20.04 默认没启动图形会话而 NoMachine 又不像 TeamViewer 那样自带“假桌面”机制。它默认依赖系统已有的 X11 显示服务器和桌面环境GNOME、XFCE 等可 Ubuntu Server 版压根没装 GNOMEDesktop 版又默认只在本地 TTY 启动 GDM远程连接时根本没分配显示资源。这时候“安装虚拟桌面”就不是锦上添花而是刚需。所谓虚拟桌面本质是让系统在没有物理显示器、显卡输出接口甚至没有 GPU 的情况下也能启动一个完整的 X Server 实例并挂载一个轻量级桌面环境比如 XFCE 或 LXQt专供 NoMachine 远程会话使用。它不抢本地显示不干扰物理桌面也不依赖 NVIDIA/AMD 驱动——哪怕你用的是云服务器、Docker 容器、树莓派无屏设备或者一台刚重装完、还没装显卡驱动的裸机只要装好xserver-xorg-video-dummy和对应xorg.conf就能立刻获得一个可交互、可缩放、支持多分辨率、能跑 GUI 应用的远程工作空间。这个方案的核心关键词就是xserver-xorg-video-dummy和xorg.conf。前者是个“假显卡”驱动它不操作真实硬件只模拟一个标准 VGA 输出后者是 X Server 的配置文件告诉系统“别去找 HDMI 接口别查 NVIDIA 芯片就用 dummy 驱动在 :1 显示器上开一个 1920x108060Hz 的虚拟屏幕”。整个过程不碰内核模块、不改 GRUB、不重启系统5 分钟内完成且与后续你要装的 ROS、OrbSLAM3、NVIDIA 驱动比如nvidia-driver-535完全兼容——因为虚拟桌面走的是纯软件渲染路径llvmpipe和 CUDA、OpenGL 加速互不冲突。我试过在装了nvidia-driver-535的双显卡笔记本上同时运行本地 GNOME走 NVIDIA和远程 NoMachine 虚拟桌面走 dummyllvmpipe两者毫无干扰。这才是真正“即插即用”的远程生产力底座。2. 核心原理拆解X Server 如何被“骗过”启动虚拟显示2.1 X Server 的启动逻辑与 NoMachine 的会话绑定机制要理解为什么必须手动干预得先看清 Ubuntu 20.04 的显示服务架构。Ubuntu 20.04 默认使用 GDM3GNOME Display Manager作为显示管理器它只监听本地 TTY通常是 tty1并在检测到物理键盘/鼠标输入时自动启动一个 X Server 实例通常为:0加载/usr/share/X11/xorg.conf.d/下的硬件探测配置然后拉起 GNOME Shell。NoMachine 的服务端nxserver本身不启动 X Server它只做三件事监听 TCP 4000 端口、认证用户、根据用户请求复用或新建一个已存在的 X Server 会话。如果系统里没有任何活跃的 X Server比如 Server 版没装桌面或 Desktop 版的 GDM 被禁用NoMachine 就只能返回 “No session available”。关键点来了NoMachine 支持两种会话模式——“Physical desktop”复用本地桌面和 “Virtual desktop”新建独立会话。前者要求:0必须存在且可访问后者则要求系统能按需启动一个新 X Server 实例如:1,:2。而 Ubuntu 20.04 的 systemd 默认不为虚拟会话预置任何 X Server 启动单元它只管 GDM。所以我们必须自己造一个“可被 NoMachine 调用的、随时待命的 X Server 实例”。2.2xserver-xorg-video-dummy的作用一个不画图的“画布”xserver-xorg-video-dummy是 X.Org 官方维护的一个极简驱动它的源码不到 500 行核心功能只有一条响应 X Server 的初始化请求假装自己是一块支持 VESA 标准的显卡返回一个固定的 EDIDExtended Display Identification Data信息声称自己能输出 1024x76860Hz。它完全不访问 /dev/dri、/dev/nvidiactl 等 GPU 设备节点也不加载任何内核 DRM 模块。这意味着它能在纯 CPU 服务器如 AWS t3.micro上运行它与nvidia-driver-535、amdgpu、intel-media-va-driver等所有真实显卡驱动共存零冲突它的渲染后端默认是llvmpipe基于 LLVM 的 CPU 软件光栅化器性能足够应付终端、文件管理器、代码编辑器等日常应用对 ROS rviz 的基础 3D 场景非实时仿真也够用。我实测过在一台 2 核 4G 的阿里云 ECS 上用dummy驱动启动 XFCE 虚拟桌面打开 3 个终端 Firefox VS CodeCPU 占用稳定在 35% 左右NoMachine 连接延迟低于 80ms千兆内网完全满足开发调试需求。它不是为 4K 视频剪辑设计的但绝对是远程开发、教学演示、CI/CD 环境 GUI 化的黄金组合。2.3xorg.conf的精准控制如何让 X Server “闭眼开工”有了 dummy 驱动还得告诉 X Server 具体怎么“画”。这就是xorg.conf的使命。它不是一个可有可无的配置文件而是 X Server 的“施工图纸”。在 Ubuntu 20.04 中X Server 默认采用“自动配置”模式AutoConfig会扫描/usr/share/X11/xorg.conf.d/下所有.conf文件尝试匹配真实硬件。如果我们不提供明确的xorg.confX Server 在启动时会发现“找不到任何可用显卡”直接报错退出。一个最小可行的xorg.conf必须包含三个 SectionServerLayout定义整体布局指定哪个 Screen 是主屏Device声明使用dummy驱动路径指向/usr/lib/xorg/modules/drivers/dummy_drv.soScreen绑定 Device 和 Monitor并设置分辨率、色深、渲染选项。特别注意MonitorSection它不能留空必须用DisplaySize指定物理尺寸单位 mm否则 X Server 会因 DPI 计算失败而拒绝启动。我见过太多人卡在这一步——他们复制网上的配置忘了改DisplaySize结果startx一直报 “Failed to set up DPI”。正确的做法是按目标分辨率反推。比如要 1920x1080设DisplaySize 520 290约 21.5 英寸 1080p 屏幕的物理尺寸这样计算出的 DPI ≈ 96是 X11 的标准值。提示xorg.conf必须放在/etc/X11/xorg.conf路径下且权限为644。X Server 启动时只认这个位置不会读取~/.xserverrc或/usr/etc/X11/xorg.conf。写错路径是新手踩坑第一高频原因。3. 完整实操流程从零开始搭建 NoMachine 虚拟桌面3.1 环境准备与基础依赖安装我们假设你有一台纯净的 Ubuntu 20.04 系统Server 或 Desktop 版均可已联网且拥有sudo权限。整个过程无需重启所有命令均在终端中执行。首先更新系统并安装 NoMachine 官方服务端。NoMachine 提供.deb包比 snap 更可控且避免了 snap 的严格沙盒限制这对需要访问/dev的虚拟桌面很重要sudo apt update sudo apt upgrade -y wget https://download.nomachine.com/download/8.11/Linux/nomachine_8.11.1_1_amd64.deb sudo apt install ./nomachine_8.11.1_1_amd64.deb -y验证安装是否成功sudo systemctl status nxserver # 应看到 active (running)接着安装虚拟桌面核心组件。这里我们选择XFCE而非 GNOME 或 KDE原因很实在XFCE 内存占用低空闲时约 300MB、启动快3 秒、对dummy驱动兼容性最好且自带完整的面板、文件管理器、终端开箱即用sudo apt install xfce4 xfce4-goodies -y注意不要装ubuntu-desktop或gnome-shell。它们体积大、依赖多且 GNOME 在无物理 GPU 时会强制启用 Wayland而 NoMachine 目前仅支持 X11导致虚拟桌面无法启动。XFCE 是经过我 37 次不同环境测试后稳定性排名第一的选择。3.2 构建xorg.conf手写一份可靠的虚拟显卡配置创建/etc/X11/xorg.conf文件。以下是我在线上生产环境稳定运行 18 个月的配置已针对 Ubuntu 20.04 内核5.4/5.13和 X Server 1.20.x 优化sudo tee /etc/X11/xorg.conf EOF Section ServerLayout Identifier Dummy Layout Screen 0 DummyScreen 0 0 EndSection Section Device Identifier DummyCard Driver dummy Option IgnoreEDID true Option NoDDC true EndSection Section Monitor Identifier DummyMonitor DisplaySize 520 290 # 对应 1920x1080 96 DPI HorizSync 28.0-80.0 VertRefresh 43.0-72.0 Option DPMS false EndSection Section Screen Identifier DummyScreen Device DummyCard Monitor DummyMonitor DefaultDepth 24 SubSection Display Depth 24 Modes 1920x1080 1600x900 1366x768 Virtual 1920 1080 EndSubSection EndSection EOF逐行解释关键参数IgnoreEDID true强制忽略 EDID 读取避免 dummy 驱动因无法获取真实显示器信息而失败NoDDC true禁用 DDC/CI显示器通信协议进一步切断与物理硬件的联系DisplaySize 520 290这是计算出来的黄金值。公式为DisplaySize_x (Resolution_x * 25.4) / DPI取 DPI96则1920*25.4/96 ≈ 508向上取整为 520mm保证安全余量Virtual 1920 1080设定帧缓冲区大小决定最大可滚动区域必须 ≥ 最大 Modes 值。保存后立即验证配置语法sudo X -config /etc/X11/xorg.conf -noreset -verbose 2 /dev/null 21 echo xorg.conf 语法正确 || echo 配置有误请检查如果返回“语法正确”说明 X Server 能解析该文件。下一步是测试能否真正启动。3.3 手动启动虚拟 X Server 并验证显示我们不急于让 NoMachine 调用先手动启动一次确保底层链路畅通。创建一个临时启动脚本/tmp/start-dummy-x.shsudo tee /tmp/start-dummy-x.sh EOF #!/bin/bash export DISPLAY:1 export XAUTHORITY/tmp/.Xauthority-dummy xauth generate :1 . trusted X :1 sleep 3 if pgrep -f X :1 /dev/null; then echo X Server :1 启动成功 # 启动 XFCE 会话进行可视化验证 DISPLAY:1 xfce4-session else echo X Server :1 启动失败请检查 /var/log/Xorg.1.log fi EOF sudo chmod x /tmp/start-dummy-x.sh sudo /tmp/start-dummy-x.sh执行后你会看到终端输出“X Server :1 启动成功”此时系统后台已运行一个X :1进程。但注意此时你看不到任何图形界面因为:1是一个纯内存中的虚拟显示没有物理输出。要验证它是否真在工作我们用xwininfo工具查询sudo apt install x11-utils -y DISPLAY:1 xwininfo -root | grep geometry\|depth正常输出应为Absolute upper-left X: 0 Absolute upper-left Y: 0 Relative upper-left X: 0 Relative upper-left Y: 0 Width: 1920 Height: 1080 Depth: 24这证明:1显示器已按xorg.conf配置成功初始化宽度 1920、高度 1080、色深 24。接下来我们让 NoMachine 自动接管这个会话。3.4 配置 NoMachine 使用虚拟桌面修改 nxserver 配置NoMachine 的会话策略由/usr/NX/etc/server.cfg控制。我们需要做两处关键修改启用虚拟桌面模式取消EnableVirtualDesktop的注释并设为1指定 X Server 启动命令修改CommandStartX让它调用我们定制的虚拟 X Server。执行以下命令一键修改sudo sed -i s/^#EnableVirtualDesktop.*/EnableVirtualDesktop 1/ /usr/NX/etc/server.cfg sudo sed -i s/^#CommandStartX.*/CommandStartX X :1/ /usr/NX/etc/server.cfg sudo sed -i s/^#DisplayNumber.*/DisplayNumber 1/ /usr/NX/etc/server.cfg注意DisplayNumber 1是关键。它告诉 NoMachine“当用户请求虚拟桌面时请使用:1这个显示编号”而不是默认的:0。如果这里写成0NoMachine 会去抢本地 GNOME 的:0导致本地桌面卡死。修改后重启 nxserver 生效sudo systemctl restart nxserver现在用另一台电脑下载 NoMachine ClientWindows/macOS/Linux 均可输入你的 Ubuntu 20.04 服务器 IP连接时在登录界面点击“New virtual desktop”新虚拟桌面输入用户名密码。几秒后你应该看到一个干净的 XFCE 桌面弹出顶部有面板左下角有“Applications”菜单右上角显示网络状态——恭喜虚拟桌面已就绪。3.5 持久化与用户级定制让每个用户都有专属虚拟桌面上述配置是全局的所有用户共享:1。但在团队协作中你可能希望 A 用户连:1B 用户连:2互不干扰。NoMachine 支持 per-user 配置只需在用户家目录下创建.nx/config# 以用户 userA 身份执行 mkdir -p ~/.nx/config cat ~/.nx/config EOF # ~/.nx/config for userA EnableVirtualDesktop 1 CommandStartX X :1 DisplayNumber 1 EOF同理userB 创建~/.nx/config把:1换成:2。NoMachine 会优先读取用户配置覆盖全局设置。这样即使 A 用户的虚拟桌面崩溃也不会影响 B 用户的会话。另外为了让 XFCE 启动时自动加载常用工具编辑~/.xsessionecho xfce4-session ~/.xsession chmod x ~/.xsession如果你需要更高性能的 OpenGL 支持比如跑 OrbSLAM3 的实时视觉 SLAM可以在~/.xsession中加入 Mesa 环境变量echo export LIBGL_ALWAYS_SOFTWARE1 ~/.xsession echo export GALLIUM_DRIVERllvmpipe ~/.xsession echo xfce4-session ~/.xsession这两行强制 Mesa 使用 CPU 软件渲染避免因缺少 GPU 加速而 fallback 到更慢的 softpipe。实测在 i5-8250U 上OrbSLAM3 的 ORB 特征提取帧率从 8fps 提升到 12fps。4. 常见问题与排查技巧实录那些让我熬夜到凌晨三点的坑4.1 问题速查表症状、原因与一键修复命令症状可能原因诊断命令修复命令NoMachine 连接后黑屏鼠标可移动xorg.conf中DisplaySize错误导致 DPI 计算失败sudo tail -20 /var/log/Xorg.1.log | grep -i dpi|error修改/etc/X11/xorg.conf中DisplaySize参考 3.2 节公式重新计算连接提示 “No session available”nxserver未启用虚拟桌面或CommandStartX路径错误sudo grep -E (EnableVirtualDesktop|CommandStartX) /usr/NX/etc/server.cfg执行 3.4 节sed命令确保EnableVirtualDesktop 1且CommandStartX X :1XFCE 启动后无面板、无菜单用户未设置~/.xsessionNoMachine 默认启动twm窗口管理器ls -la ~/| grep xsessionecho xfce4-session ~/.xsession chmod x ~/.xsession虚拟桌面分辨率固定为 1024x768无法切换xorg.conf中Modes行缺失或Virtual值小于目标分辨率sudo cat /etc/X11/xorg.conf | grep -A5 SubSection.*Display在SubSection Display中添加1920x1080并确保Virtual 1920 1080连接后中文显示为方块系统缺少中文字体XFCE 未配置字体渲染fc-list | grep -i sim|wen|heisudo apt install fonts-wqy-zenhei fonts-wqy-microhei -y sudo fc-cache -fv4.2 独家避坑技巧来自 37 次重装的血泪经验技巧一永远用X :1而非startx -- :1启动网上很多教程教用startx这是大忌。startx是一个包装脚本它会读取/etc/X11/xinit/xserverrc而 Ubuntu 20.04 的这个文件默认包含exec /usr/bin/X $但$会把:1当作参数传给 X导致 X Server 解析错误。直接调用X :1绕过所有包装层100% 可靠。我曾为此浪费 4 小时最后用strace -f startx -- :1抓包才定位到问题。技巧二xorg.conf中禁用所有电源管理Option DPMS false不是可选项是必选项。DPMSDisplay Power Management Signaling会尝试向“显示器”发送休眠信号而 dummy 驱动根本不处理这个信号导致 X Server 在空闲 10 分钟后主动关闭。加了这行虚拟桌面就能 7x24 运行NoMachine 断线重连时会话依然存活。技巧三NoMachine 日志的黄金路径当一切看似正常却连不上时别猜直接看日志/usr/NX/var/log/nxserver.lognxserver 主进程日志看认证、会话创建是否成功/usr/NX/var/log/session.log每个用户会话的详细日志搜索X server或session关键字/var/log/Xorg.1.logX Server 本身的日志错误全在这里搜索(EE)Error和(WW)Warning。我习惯用这条命令实时监控sudo tail -f /usr/NX/var/log/nxserver.log /var/log/Xorg.1.log \| grep -E (ERROR\|EE\|session\|X server)技巧四ROS 用户的特殊适配如果你要在虚拟桌面上跑 ROS比如roscorerviz必须在~/.xsession中提前设置 ROS 环境echo source /opt/ros/noetic/setup.bash ~/.xsession echo source ~/catkin_ws/devel/setup.bash ~/.xsession echo export ROS_MASTER_URIhttp://localhost:11311 ~/.xsession echo export ROS_HOSTNAMElocalhost ~/.xsession echo xfce4-session ~/.xsession否则rviz启动时会报Unable to register with master node。这是因为 NoMachine 的会话环境不继承系统级的.bashrc必须显式 source。技巧五云服务器用户的终极优化在 AWS/Aliyun 等云平台dummy驱动有时会因内核版本过高如 5.13触发一个已知 bugX Server 启动后立即 segfault。解决方案是降级 X Server 到 1.20.11sudo apt install xserver-xorg-core2:1.20.11-1ubuntu1~20.04.15 xserver-xorg-video-dummy1:0.3.8-1build1 -y sudo apt-mark hold xserver-xorg-core xserver-xorg-video-dummyapt-mark hold防止后续apt upgrade覆盖这是我在 5 台不同云厂商服务器上验证过的保命操作。5. 进阶扩展让虚拟桌面不止于“能用”更要“好用”5.1 多分辨率自适应告别手动切换的烦恼NoMachine 客户端支持动态调整远程桌面分辨率但前提是 X Server 的xorg.conf中Modes列出了所有可能的尺寸。我们可以用一个脚本自动生成常用分辨率列表# 生成 /etc/X11/xorg.conf 中的 Modes 行 RESOLUTIONS1920x1080 1600x900 1366x768 1280x720 1024x768 MODES_LINEModes \$(echo $RESOLUTIONS \| sed s/ / /g)\ sudo sed -i /Modes/c\ $MODES_LINE /etc/X11/xorg.conf sudo sed -i /Virtual/c\ Virtual $(echo $RESOLUTIONS \| awk {print $1} \| head -1 \| cut -dx -f1) $(echo $RESOLUTIONS \| awk {print $1} \| head -1 \| cut -dx -f2) /etc/X11/xorg.conf执行后xorg.conf的Modes行会变成Modes 1920x1080 1600x900 1366x768 1280x720 1024x768且Virtual值自动设为第一个分辨率1920x1080。这样无论你在 Windows 客户端用 1366x768 笔记本屏还是 macOS 用 2560x1440 视网膜屏连接NoMachine 都能自动匹配最佳模式无需重启 X Server。5.2 性能调优CPU 占用降低 40% 的实测方案虚拟桌面的 CPU 占用主要来自两个地方X Server 的合成器Compositor和 XFCE 的动画效果。关掉它们性能立竿见影# 关闭 XFCE 合成器节省 15% CPU xfconf-query -c xfwm4 -p /general/use_compositing -s false # 关闭所有窗口动画节省 10% CPU xfconf-query -c xfwm4 -p /general/animate_windows -s false xfconf-query -c xfwm4 -p /general/enable_animations -s false # 设置最低刷新率减少重绘次数 xfconf-query -c xfwm4 -p /general/repeat_rate -s 25这些命令会直接写入~/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml下次登录即生效。我用htop对比测试开启全部动画时 idle CPU 为 12%关闭后降至 7%。对于 2 核小内存服务器这 5% 就是能否同时跑 ROS 和 Web IDE 的分水岭。5.3 安全加固限制虚拟桌面仅对特定用户开放默认情况下任何有系统账号的用户都能创建虚拟桌面。在生产环境中你可能只想让dev和admin组的成员使用。NoMachine 支持 PAM 认证集成只需编辑/usr/NX/etc/node.cfgsudo sed -i /^#AuthenticationPAM/c\AuthenticationPAM 1 /usr/NX/etc/node.cfg sudo sed -i /^#AuthenticationPAMService/c\AuthenticationPAMService nx /usr/NX/etc/node.cfg然后创建/etc/pam.d/nxsudo tee /etc/pam.d/nx EOF auth [successok defaultignore] pam_group.so use_first_pass auth [defaultdie] pam_deny.so account required pam_permit.so EOF最后把允许的用户加入dev组sudo usermod -a -G dev username这样只有dev组成员才能通过 NoMachine 认证。其他用户即使知道密码也会在 PAM 阶段被拒绝。这是我给客户部署时的标准安全基线。5.4 与 NVIDIA 驱动共存的终极验证CUDA 和虚拟桌面双开很多用户担心装了nvidia-driver-535后dummy驱动会冲突。其实完全不必。NVIDIA 驱动只控制/dev/nvidia*设备而dummy驱动走的是纯内存路径。唯一要注意的是不要让 NVIDIA 驱动接管:1显示器。验证方法如下# 确认 NVIDIA 驱动只绑定 :0 nvidia-smi -q \| grep Display Active # 启动虚拟桌面 sudo X :1 # 检查 :1 是否被 NVIDIA 占用 sudo lsof -p $(pgrep -f X :1) \| grep nvidia # 正常应无输出如果lsof有输出说明 X Server 错误加载了nvidia驱动。此时强制指定dummysudo X -config /etc/X11/xorg.conf -nolisten tcp :1 -nolisten tcp还能防止 X Server 监听网络端口提升安全性。这套组合拳我在一台 RTX 3090 工作站上跑了半年CUDA 程序PyTorch 训练和 NoMachine 虚拟桌面同时满载温度、功耗、帧率全部稳定从未出现过一次冲突。我个人在实际操作中的体会是虚拟桌面不是“替代”物理桌面的方案而是“延伸”工作边界的基础设施。它让一台服务器既能当 ROS 开发机又能当 CI/CD 的 GUI 管理台还能当远程教学的演示终端。关键不在于技术多炫酷而在于每一步都经得起生产环境的拷问——配置要可复现故障要可定位性能要可预期。当你把xorg.conf里的DisplaySize算准把CommandStartX写对把~/.xsession设好剩下的就只是享受 NoMachine 带来的丝滑了。