Showing Posts From

Chromium

Missing X server or $DISPLAY:无头环境跑浏览器的正确姿势

在服务器 / 容器里想跑 Chromium、Electron、Playwright,报错: [...] ozone_platform_x11.cc:259] Missing X server or $DISPLAY意思很直白——程序想弹 GUI,但当前环境没 X11 显示服务。三个典型场景。 场景一:SSH 到 Linux 服务器 SSH 登进去的 shell 默认没有桌面: ssh root@server google-chrome # 直接报 Missing X server两种解法: Headless 模式(首选) google-chrome --headless=new --disable-gpu --no-sandbox https://example.comPlaywright: browser = playwright.chromium.launch(headless=True)Puppeteer: const browser = await puppeteer.launch({ headless: true });非 headless 场景用 X11 转发 ssh -X root@server或用 -Y(信任模式,速度更快)。前提是本机有 X server(Mac 上是 XQuartz,Windows 上是 VcXsrv/X410)。 场景二:Docker 容器里 容器默认没 X server: $ echo $DISPLAY (空)首选还是 headless。要真的跑 GUI 就靠 Xvfb(虚拟帧缓冲): apt update && apt install -y xvfb xvfb-run -a chromium https://example.comxvfb-run 会在后台起一个虚拟 X server 让程序连。Playwright 官方镜像就自带这套。 如果显示环境变量已经写了 DISPLAY=:1,但仍然报错,那是因为 :1 对应的 X server 根本没起: ls /tmp/.X11-unix/看不到 X0 / X1 就是没启动。容器里手动 export DISPLAY=:1 是没用的——DISPLAY 只是"连哪个 X server",不会创建 X server。 场景三:WSL WSL2 现在原生支持 WSLg,一般不会碰到这错。老 WSL1 或者关了 WSLg 的话: export DISPLAY=:0 sudo apt install x11-apps xclock # 测试有没有 GUI再不行就装个 X server(Windows 上 VcXsrv / X410)。 快速判断清单 先看几个变量: echo $DISPLAY # 应该是 :0 或 :1 ls /tmp/.X11-unix/ # 应该有 X0 之类的 socket ps aux | grep -E 'Xorg|Xvfb' # 有 X server 进程在跑 hostname # 类似 6e6340e2e0d2 基本是容器 cat /proc/1/cgroup # 看到 docker 关键字 = 容器对号入座:现象 判断DISPLAY 空 没有桌面环境,用 headless 或 XvfbDISPLAY 有但 X11 socket 目录空 声明了但 X server 没起hostname 是短哈希 Docker 容器WSL 里 xclock 不动 WSL 侧 X server 没通一句话总结 服务器 / 容器跑浏览器,能 headless 就 headless,非要 GUI 上 Xvfb。 手动改 $DISPLAY 只是告诉客户端连哪儿,从来不会凭空生出一个 X server。