Ubuntu VPS 搭建 XFCE 远程桌面:从 xrdp 安装到秒断修复、中文输入与 WorkBuddy 实战

在一台低配 Ubuntu VPS 上用 xrdp + XFCE 搭可用远程桌面的完整踩坑记录:用户创建、startwm.sh 防秒断、降分辨率关特效、Chrome 替代 snap 版 Firefox、WorkBuddy 启动与权限处理,以及 fcitx5 中文输入

在一台只有 2~4G 内存的 Ubuntu VPS 上想要图形界面,GNOME/KDE 太重、跑起来又卡又容易崩。XFCE 是更现实的选择:轻量、稳定、依赖少。本文记录一套能长期稳定跑起来的组合 xrdp + XFCE,以及我在真机上踩过的每一个坑——尤其是「连上秒断」「中文输入法不生效」「snap 版浏览器起不来」「WorkBuddy 闪退」这几类。所有命令都来自实际操作,可直接照抄。

环境假设:Ubuntu 22.04/24.04,全新 VPS,已能 SSH 登录,root 权限。

先想清楚:为什么是 xrdp + XFCE

  • XFCE 轻量:空闲内存占用几百 MB 量级,在低配 VPS 上能留足余量给浏览器和应用。GNOME 在最小安装服务器上经常直接弹出 “Oh no! Something has gone wrong” 崩溃。
  • xrdp 原生 RDP:Windows / macOS / 手机都有现成的远程桌面客户端,不用额外装 VNC viewer。默认端口 3389。
  • 关键结论:xrdp 默认会去调 GNOME,而最小安装里没有完整的 GNOME,所以必须显式强制 XFCE,否则一定崩。这是后面所有配置的前提。

第一步:创建专用登录用户

不要直接用 root 登录远程桌面,单独建一个普通用户(本文用 napnap,uid 1001)。很多桌面组件在 root 下行为异常,且安全风险大。

1
2
3
4
5
# 交互式创建(会提示设密码)
sudo adduser napnap

# 给 sudo 权限(方便后面装软件)
sudo usermod -aG sudo napnap

如果用非交互方式:

1
2
3
sudo useradd -m -s /bin/bash napnap
sudo passwd napnap
sudo usermod -aG sudo napnap

记一下 uid,后面排查会用到:

1
2
id napnap
# uid=1001(napnap) gid=1001(napnap) ...

第二步:安装 XFCE

1
2
sudo apt update
sudo apt install -y xfce4 xfce4-goodies

xfce4-goodies 是可选组件包(终端、电源管理、截图等小工具),建议装上,体验完整很多。

必装的配套:dbus-x11。 这一步很多人漏掉,后果就是后面「秒断」。XFCE 启动依赖 D-Bus 会话总线,dbus-x11 提供 dbus-launch:

1
sudo apt install -y dbus-x11

第三步:安装 xrdp

1
2
3
sudo apt install -y xrdp
sudo systemctl enable --now xrdp
sudo systemctl status xrdp --no-pager

装完确认两点:

  1. 服务 active (running);
  2. 3389 在监听:
1
2
sudo ss -tlnp | grep 3389
# LISTEN 0 2 *:3389 *:* users:(("xrdp",pid=...,fd=11))

如果开了防火墙(ufw),放行端口:

1
sudo ufw allow 3389/tcp

云厂商侧(AWS 安全组 / 腾讯云安全组等)也要放行 3389 入站,否则客户端会一直「无法连接」。

登录用户的会话文件:在 napnap 家目录放一个 .xsession,告诉 xrdp 用 XFCE 会话:

1
2
echo "xfce4-session" > /home/napnap/.xsession
chown napnap:napnap /home/napnap/.xsession

即使后面用 startwm.sh 直接 exec startxfce4,这个文件也建议保留,能避免 xrdp 找不到会话类型时回退到 GNOME。

第四步:改 startwm.sh——解决「连上秒断」

这是整篇文章最关键的坑。不改这里,连上去会黑屏一下立刻回到登录界面,日志里写着 Window manager exited quickly (0 secs)。

xrdp 真正执行的是 /etc/xrdp/startwm.sh。默认脚本在最小安装下起不来 XFCE。把整文件替换成下面这个经过验证可用的版本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/sh
# 1. 补回 Xsession 会做的基础环境(语言、编码)
if [ -r /etc/default/locale ]; then
  . /etc/default/locale
  export LANG LANGUAGE
fi
# 2. XFCE / D-Bus 用户总线依赖 XDG_RUNTIME_DIR,没有就建
if [ -z "$XDG_RUNTIME_DIR" ]; then
  XDG_RUNTIME_DIR=/run/user/$(id -u)
  export XDG_RUNTIME_DIR
  [ -d "$XDG_RUNTIME_DIR" ] || mkdir -p "$XDG_RUNTIME_DIR"
fi
# 3. 阻止 systemd 误判窗管退出、清掉可能失效的旧 dbus 地址
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
# 4. 强制用 XFCE,并把所有输出重定向到日志方便排查
exec startxfce4 > /home/napnap/startxfce4.log 2>&1

写入方式(root):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
sudo cp /etc/xrdp/startwm.sh /etc/xrdp/startwm.sh.bak   # 先备份
sudo tee /etc/xrdp/startwm.sh > /dev/null <<'EOF'
#!/bin/sh
if [ -r /etc/default/locale ]; then
  . /etc/default/locale
  export LANG LANGUAGE
fi
if [ -z "$XDG_RUNTIME_DIR" ]; then
  XDG_RUNTIME_DIR=/run/user/$(id -u)
  export XDG_RUNTIME_DIR
  [ -d "$XDG_RUNTIME_DIR" ] || mkdir -p "$XDG_RUNTIME_DIR"
fi
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec startxfce4 > /home/napnap/startxfce4.log 2>&1
EOF
sudo chmod +x /etc/xrdp/startwm.sh

为什么这样写能防秒断:

  • exec startxfce4 替代默认的 startwm 调用链,直接把 XFCE 顶上来,不让 xrdp 去碰 GNOME。
  • XDG_RUNTIME_DIR 不设置的话,XFCE 的很多组件(通知、电源、面板插件)找不到用户运行时目录,瞬间退出。
  • unset DBUS_SESSION_BUS_ADDRESS 之后,XFCE 会用第二步装的 dbus-x11 重新拉起一条干净的会话总线;前提是 dbus-x11 已装,否则又会 0 秒退。
  • 把所有输出重定向到 /home/napnap/startxfce4.log 是排错神器:一旦桌面起不来,SSH 里 tail /home/napnap/startxfce4.log 看真实报错,比猜快十倍。

另一种写法是用 exec dbus-launch --exit-with-session startxfce4,显式由 dbus-launch 托管会话。本文的 unset + exec startxfce4 在装了 dbus-x11 时同样稳定,且日志更干净,故采用它。

改完重启 xrdp 让配置生效:

1
sudo systemctl restart xrdp

第五步:用客户端连上去

  • Windows:自带「远程桌面连接」(mstsc),计算机填 VPS_IP:3389,用户名 napnap,输密码。
  • 首次连接如果秒断,等几秒重连一次——xrdp 重启后首连偶尔会瞬时抖动。
  • 连上后如果桌面能停留,说明核心配置已通,下面都是体验优化。

第六步:性能优化——降分辨率、关合成特效

低配 VPS 上远程桌面最容易卡。两招见效最快:

1. 降分辨率。云桌面里同时跑 XFCE + 浏览器 + 应用,1080p 很吃带宽和内存。Windows 远程桌面客户端里「显示」选项把分辨率调到 1366×768 或 1280×720,颜色深度 16/24 位即可。也可以在 xrdp 登录界面前的高级选项里设。

2. 关掉窗口合成特效(Compositor)。XFCE 的窗口半透明、阴影、动画依赖合成器,在虚拟 X 会话里既卡又容易花屏。关掉:

  • 图形操作:菜单 → 设置 → 窗口管理器微调(Window Manager Tweaks)→ 「合成器」标签页 → 取消勾选「启用显示合成」(Enable display compositing)。
  • 命令行(需当前已登录桌面会话):
1
xfconf-query -c xfwm4 -p /general/use_compositing -s false

注意:xfconf-query 依赖当前会话的 D-Bus,必须在一个已经起来的 XFCE 会话里跑;纯 SSH 下会报 D-Bus 错误,那是正常的,去桌面里点界面关即可。

第七步:浏览器——用 Chrome deb 替代 snap 版 Firefox

Ubuntu 24.04 的 apt install firefox 实际装的是 snap 版,而 xrdp 会话不在 snap 的 cgroup 里,启动会直接报错:

1
session-*.scope is not a snap cgroup

所以别用 snap 版 Firefox。先卸干净,再装 Chrome 的 deb 包:

1
2
3
4
5
6
7
# 卸掉 snap firefox(如果装过)
sudo snap remove --purge firefox 2>/dev/null
sudo apt remove --purge -y firefox 2>/dev/null

# 装 Chrome 稳定版 deb
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb

装完在 XFCE 菜单 → 互联网 里就能打开 Chrome。deb 版不受 snap cgroup 限制,远程桌面里正常起。

第八步:在云桌面里装 WorkBuddy

WorkBuddy 是 Electron 应用。官网下载页没给 Ubuntu/Fedora 的入口(只写了「到系统应用商店下载」),但官方其实构建了 deb/rpm,就挂在自家 CDN 上,通过更新接口就能拿到最新下载地址。先确认架构:

1
uname -m   # x86_64 → 用 x64;aarch64 → 用 arm64

Ubuntu / Debian 系(deb):

1
2
3
4
5
# 从官方更新接口取最新 deb 下载地址(需要 jq;没有就浏览器打开该 URL 复制 url 字段)
url=$(curl -s "https://copilot.tencent.com/v2/update?platform=workbuddy-linux-x64-deb" | jq -r '.url')
curl -L -O "$url"
sha256sum WorkBuddy-linux-x64-deb-*.deb   # 见下方「哈希对不上的提醒」
sudo apt install ./WorkBuddy-linux-x64-deb-*.deb

apt install 会自动解析标准库依赖(libgtk-3-0、libnss3、libsecret-1-0 等),装到 /opt/WorkBuddy,二进制在 /opt/WorkBuddy/workbuddy,并自动注册 /usr/bin/workbuddy、把 chrome-sandbox 设为 4755(setuid)。装完从菜单或终端敲 workbuddy 即可启动。

Fedora / RHEL 系(rpm):换 rpm 通道,其余同理:

1
2
3
url=$(curl -s "https://copilot.tencent.com/v2/update?platform=workbuddy-linux-x64-rpm" | jq -r '.url')
curl -L -O "$url"
sudo dnf install ./WorkBuddy-linux-x64-rpm-*.rpm

ARM 机器把 platform 里的 x64 换成 arm64 即可(通道:workbuddy-linux-arm64-deb / workbuddy-linux-arm64-rpm)。

关于「第三方镜像失效」:之前 mirror.workbuddy.cn 这类博客里的地址是假的。正道是用上面的官方更新接口动态取地址,不要硬编码 URL(链接里的构建号每次发版都变)。

哈希对不上的提醒:接口 JSON 里的 sha256hash 字段实测和下载文件对不上(疑似算的不是这个文件),下载后自己 sha256sum 留档即可,别拿接口的值当校验标准。另外应用内更新在 Linux 上是死循环(提示去官网下、官网又没 Linux 入口),所以升级就重跑一遍上面的接口取新包。

启动与「闪退」处理。在虚拟 X 会话里,Electron/Chromium 常栽在两处:

  1. chrome-sandbox 权限不对 → FATAL sandbox 错误。修复:
1
2
sudo chown root:root /opt/WorkBuddy/chrome-sandbox
sudo chmod 4755 /opt/WorkBuddy/chrome-sandbox   # 即 -rwsr-xr-x

官方 deb 的 postinst 安装时会把 chrome-sandbox 设成 4755,干净安装一般能直接启动;若某次安装/升级后权限不对、或你是手动解包的方式装的,闪退复发时按上面重设一次即可。

  1. 没有 GPU / /dev/shm 太小 → 渲染进程崩。启动参数加上:
1
/opt/WorkBuddy/workbuddy --no-sandbox --disable-gpu --disable-dev-shm-usage

为了方便,做一个包装脚本放进 PATH,以后终端敲 workbuddy 就带参数:

1
2
3
4
5
sudo tee /usr/local/bin/workbuddy > /dev/null <<'EOF'
#!/bin/sh
exec /opt/WorkBuddy/workbuddy --no-sandbox --disable-gpu --disable-dev-shm-usage "$@"
EOF
sudo chmod +x /usr/local/bin/workbuddy

桌面菜单的 .desktop 里 Exec= 也要指向带参数的命令,否则双击图标仍可能闪退。

第九步:中文输入法 fcitx5

XFCE 默认没有中文输入。装 fcitx5:

1
2
3
4
5
# 先确认没装旧的 / 冲突的,避免环境变量打架
# (如已装 ibus,可保留,但本文统一用 fcitx5)

sudo apt install -y fcitx5 fcitx5-chinese-addons fcitx5-frontend-all im-config
im-config -n fcitx5

关键坑:xrdp 的 startwm.sh 不会读 ~/.profile,所以平时写在 ~/.profile / ~/.xinitrc 里的输入法环境变量在远程桌面里根本不生效。必须把这几行写进 /etc/xrdp/startwm.sh,放在 exec startxfce4 之前(见第四步):

1
2
3
4
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export SDL_IM_MODULE=fcitx

改完 startwm.sh 再 sudo systemctl restart xrdp,重连后:

  1. 桌面右上角托盘出现 fcitx 图标;
  2. 右键图标 → 配置(Configure)→ 加「拼音」或「双拼」输入法;
  3. Ctrl + 空格 切换中英文。托盘里也能手动点选输入法。

WorkBuddy 能帮忙修:如果在云桌面里怎么都切不出中文,WorkBuddy 会弹提示「可以让 WorkBuddy 修复输入法问题」,直接让它跑一遍修复即可,省得自己逐个排查环境变量。本质就是确保 fcitx5 的 GTK_IM_MODULE / QT_IM_MODULE / XMODIFIERS 在远程会话里真正生效——所以前面才强调要把这几行写进 startwm.sh,而不是只留在 ~/.profile。

第十步:会话管理与排错——避免「logout 后登不上」

xrdp 默认「断线不杀会话」。如果反复重启 xrdp,旧 xrdp-sesman 进程不一定被杀干净,会留下多个 sesman 实例和孤儿 Xorg 会话(:10、:11 之类),多个 sesman 抢同一个会话 socket,结果就是 logout 后再也登不上、卡在登录界面。

在 /etc/xrdp/sesman.ini 打开「断开即杀」,让每次登录都是干净新会话:

1
2
3
4
sudo sed -i -E 's/^(KillDisconnected=).*/\1true/; s/^(DisconnectedTimeLimit=).*/\10/' /etc/xrdp/sesman.ini
sudo grep -iE "KillDisconnected|DisconnectedTimeLimit" /etc/xrdp/sesman.ini
# 应输出 KillDisconnected=true 和 DisconnectedTimeLimit=0
sudo systemctl restart xrdp

万一已经出现「登不上」,SSH 里清一遍残留再重启:

1
2
3
4
5
6
7
sudo systemctl stop xrdp
sudo pkill -9 -f xrdp
sleep 1
sudo rm -f /var/run/xrdp/sesman.sock /tmp/.X11-unix/X10 /tmp/.X11-unix/X11
sudo systemctl start xrdp
# 验证:应只剩 1 个 xrdp + 1 个 xrdp-sesman,没有孤儿 Xorg :10/:11
ps aux | grep -E "xrdp|Xorg" | grep -v grep

常见问题排查

客户端一直「无法连接 / 连不上」

  • 3389 没监听:sudo ss -tlnp | grep 3389;服务没起就 sudo systemctl restart xrdp。
  • 防火墙/安全组没放行 3389 入站(最常见)。
  • VPS 是内网 IP,没绑公网弹性 IP 或没做端口映射。

连上后秒断(黑屏一下回登录界面)

  • 看日志:sudo tail -n 30 /var/log/xrdp-sesman.log 若有 exited quickly (0 secs),就是 startwm.sh 问题。
  • 看 tail -n 50 /home/napnap/startxfce4.log 的真实报错。
  • 确认 dbus-x11 已装、XDG_RUNTIME_DIR 那段已写进 startwm.sh。

桌面能进但很卡

  • 降分辨率到 1280×720 / 1366×768。
  • 关掉窗口合成特效(见第六步)。
  • 内存紧张就加 swap 兜底:sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile && echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab。

中文输入法切不出来

  • 确认 GTK_IM_MODULE/QT_IM_MODULE/XMODIFIERS 已写进 startwm.sh(不是 ~/.profile),并重连。
  • im-config -n fcitx5 后重启会话;托盘里确认输入法已添加。

浏览器起不来(snap cgroup 报错)

  • 卸 snap 版 Firefox,改装 Chrome deb(见第七步)。

WorkBuddy 闪退

  • 重设 chrome-sandbox 为 4755,或用 --no-sandbox --disable-gpu --disable-dev-shm-usage 启动(见第八步)。

整套下来,一台 2~4G 的 Ubuntu VPS 就能当一个长期稳定、带中文输入、能开浏览器和 WorkBuddy 的云桌面用。核心就三句话:强制 XFCE 别让 xrdp 碰 GNOME、startwm.sh 把 dbus 和 XDG_RUNTIME_DIR 补好防秒断、snap 类应用换成 deb 版。剩下的都是性能与体验的微调。

使用 Hugo 构建
主题 Stack 由 Jimmy 设计