diff --git a/docs/LINUX_GUIDE.md b/docs/LINUX_GUIDE.md index cc07e95..cecfd06 100644 --- a/docs/LINUX_GUIDE.md +++ b/docs/LINUX_GUIDE.md @@ -89,6 +89,7 @@ pgrep -a Xvfb | `CODEX_DESKTOP_EXECUTABLE_PATH` | Electron 可执行文件路径 | `/tmp/codex-desktop-linux/codex-app/electron` | | `CODEX_CLI_PATH` | Codex CLI 二进制路径 | `/opt/codex-cli/codex` | | `CODEX_HOME` | Codex 配置目录 | `~/.codex` | +| `OPENCODEX_HEADLESS_ELECTRON` | 设为 `1` 时追加无头服务器所需 Electron 参数 | `1` | `DISPLAY` 指向 Xvfb。其余变量让 OpenCodex 知道 Electron 和 Codex CLI 的位置,以及配置文件存放路径。 @@ -100,22 +101,19 @@ pgrep -a Xvfb const officialRuntimeArgs = [`--user-data-dir=${officialUserDataDir}`]; ``` -在无头 Linux 上需改为: - -```js -const officialRuntimeArgs = [ - `--user-data-dir=${officialUserDataDir}`, - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-dev-shm-usage', -]; -``` +无头 Linux 上不需要改动源码:设置环境变量 `OPENCODEX_HEADLESS_ELECTRON=1`, +launcher 与 dev runner 会在官方隐藏运行时之外追加以下参数。 | 参数 | 说明 | |------|------| | `--no-sandbox` | 服务器环境下 Chrome 沙箱通常不可用(root 运行或容器环境),不加会导致 Electron 启动失败 | -| `--disable-setuid-sandbox` | 配合 `--no-sandbox` 禁用 setuid 辅助进程 | -| `--disable-dev-shm-usage` | 避免 `/dev/shm` 过小(容器默认 64MB)导致崩溃,改用普通内存 | +| `--headless` | 让窗口不依赖真实显示服务,配合 Xvfb 使用 | +| `--disable-gpu` | 无 GPU 的服务器上 GPU 进程会 FATAL 并让 gateway 收到 SIGTRAP 退出 | + +若 `/dev/shm` 过小(容器默认 64MB),可再额外设置 `--disable-dev-shm-usage`。 + +判据:设置该变量后 `systemctl show -p Environment` 或进程 cmdline 中应能看到上述三个参数; +不设置时行为与桌面端完全一致(参数列表为空)。 ## 启动 OpenCodex diff --git a/gateway/dev/run-gateway.cjs b/gateway/dev/run-gateway.cjs index ad90cd9..8a6de67 100644 --- a/gateway/dev/run-gateway.cjs +++ b/gateway/dev/run-gateway.cjs @@ -10,6 +10,7 @@ const { } = require("../../shared/gateway-lifecycle.cjs"); const { hiddenRuntimeGcmCommandLineArgs, + headlessRuntimeCommandLineArgs, isolateHiddenRuntimeGcmStoresForUserData, } = require("../runtime/electron/hidden-runtime-command-line.cjs"); @@ -119,6 +120,8 @@ async function main() { const officialRuntimeArgs = [ `--user-data-dir=${officialUserDataDir}`, ...hiddenRuntimeGcmCommandLineArgs(process.env), + // 无头服务器适配走环境变量开关,保持仓库默认行为与桌面端一致(见 docs/LINUX_GUIDE.md)。 + ...headlessRuntimeCommandLineArgs(process.env), ]; spawnGateway(officialRuntime, officialRuntimeArgs); diff --git a/gateway/runtime/electron/hidden-runtime-command-line.cjs b/gateway/runtime/electron/hidden-runtime-command-line.cjs index c278e50..bd43aae 100644 --- a/gateway/runtime/electron/hidden-runtime-command-line.cjs +++ b/gateway/runtime/electron/hidden-runtime-command-line.cjs @@ -5,6 +5,7 @@ const UNUSED_HIDDEN_RUNTIME_FEATURES = ["PushMessaging"]; const UNUSED_HIDDEN_RUNTIME_BLINK_FEATURES = ["PushMessaging"]; const HIDDEN_RUNTIME_GCM_HOLD_PATH = "/__opencodex-internal/gcm-checkin-hold"; const HIDDEN_RUNTIME_GCM_STORE_BACKUP = "GCM Store.opencodex-disabled"; +const HEADLESS_RUNTIME_ARGS_ENV = "OPENCODEX_HEADLESS_ELECTRON"; function appendMergedSwitch(commandLine, name, additions) { const existing = @@ -98,6 +99,19 @@ function hiddenRuntimeGcmHoldUrl(env = process.env) { return `http://127.0.0.1:${safePort}${HIDDEN_RUNTIME_GCM_HOLD_PATH}`; } +/** + * 无头服务器(无 GPU / 无 X 11 显示)所需的额外 Electron 参数。 + * 由 OPENCODEX_HEADLESS_ELECTRON 环境变量开关,默认不改变桌面端行为: + * 不加 --no-sandbox 时 Chromium 在 root 或无用户命名空间的环境里会启动失败, + * 不加 --disable-gpu 时 GPU 进程会 FATAL 并让 gateway 收到 SIGTRAP 退出, + * --headless 让窗口不依赖真实显示服务。详见 docs/LINUX_GUIDE.md。 + */ +function headlessRuntimeCommandLineArgs(env = process.env) { + const enabled = String(env?.[HEADLESS_RUNTIME_ARGS_ENV] ?? "").trim().toLowerCase(); + if (!["1", "true", "yes", "on"].includes(enabled)) return []; + return ["--no-sandbox", "--headless", "--disable-gpu"]; +} + function hiddenRuntimeGcmCommandLineArgs(env = process.env) { const holdUrl = hiddenRuntimeGcmHoldUrl(env); /** @@ -151,6 +165,8 @@ module.exports = { hiddenRuntimeGcmStorePaths, hiddenRuntimeGcmCommandLineArgs, hiddenRuntimeGcmHoldUrl, + HEADLESS_RUNTIME_ARGS_ENV, + headlessRuntimeCommandLineArgs, isolateHiddenRuntimeGcmStore, isolateHiddenRuntimeGcmStoresForUserData, }; diff --git a/launcher/main.cjs b/launcher/main.cjs index 6dbb808..7a5d531 100644 --- a/launcher/main.cjs +++ b/launcher/main.cjs @@ -25,6 +25,7 @@ const { } = require("../shared/gateway-lifecycle.cjs"); const { hiddenRuntimeGcmCommandLineArgs, + headlessRuntimeCommandLineArgs, isolateHiddenRuntimeGcmStoresForUserData, } = require("../gateway/runtime/electron/hidden-runtime-command-line.cjs"); const packageMetadata = require("../package.json"); @@ -882,6 +883,8 @@ async function startGatewayOnce() { const officialRuntimeArgs = [ `--user-data-dir=${officialUserDataDir}`, ...hiddenRuntimeGcmCommandLineArgs({ PORT: String(gatewayState.port) }), + // 无头服务器(无 GPU/无 X)通过环境变量开关追加 Electron 参数,桌面端默认不受影响。 + ...headlessRuntimeCommandLineArgs(process.env), ]; const childEnv = { ...process.env,