在服务器上给服务单独创建一个低权限用户,是很常见的部署习惯。问题是,安装脚本如果中途默认执行需要 root 权限的可选步骤,就可能把一次普通安装变成“卡在半路”的状态。
NousResearch/hermes-agent issue #25816 记录的就是这个场景:在 Debian 上用专门的非 sudo 用户安装 Hermes 时,安装器执行 Playwright Chromium 依赖步骤,停在:
[sudo] password for hermes:
这个用户没有 sudo 权限,无法输入有效密码。安装流程因此阻塞,后续 setup_path() 没有执行,最终系统里连可用的 hermes 命令都没有。
这篇文章从安装顺序、权限边界和可选依赖处理三个角度,客观拆一下这个问题。
问题现象:安装器停在 Playwright 浏览器依赖步骤
issue 里的环境很明确:
OS: Debian 12 / bookworm
用户: dedicated non-sudo system service user,例如 hermes
Hermes: v0.13.0
Python: 3.11.15
安装过程先正常走到 Node.js 依赖安装完成:
✓ Node.js dependencies installed
→ Installing browser engine (Playwright Chromium)...
→ Playwright may request sudo to install browser system dependencies (shared libraries).
→ This is standard Playwright setup — Hermes itself does not require root access.
Installing dependencies...
Switching to root user to install dependencies...
[sudo] password for hermes:
关键点在这条命令:
npx playwright install --with-deps chromium
--with-deps 会尝试安装浏览器运行所需的系统依赖。在 Debian / Ubuntu 这类系统上,它可能调用 apt,需要 root 或 sudo 权限。
如果当前用户是非 sudo 服务用户,安装器就会卡在 sudo 密码提示上。
为什么这不只是“浏览器没装上”?
单看 Playwright,浏览器依赖失败似乎只是浏览器工具不可用。
但 issue 指出,这个步骤发生得太早。
安装器主流程大致是:
install_deps
install_node_deps # Playwright --with-deps 在这里卡住
setup_path # 还没执行
...
也就是说,Playwright 浏览器步骤在 setup_path() 之前。
当安装卡住或被用户中断时,后果不是“浏览器功能暂时不可用”,而是:
Hermes 安装没有收尾。
具体表现包括:
1. hermes launcher shim 没有创建; 2. hermes doctor 无法运行; 3. 直接运行仓库里的 raw entry point,可能绕过 venv launcher,用到系统 Python; 4. 进而出现类似:
ModuleNotFoundError: No module named 'dotenv'
这就是半安装状态比单个可选组件失败更麻烦的原因。
触发条件:非 sudo 用户 + Playwright --with-deps
可以把触发条件归纳为三项:
1. 使用 Debian / Ubuntu 等需要系统包依赖的环境;
2. 用专门的服务用户安装 Hermes;
3. 该服务用户没有 sudo 权限,或不能 passwordless sudo。
服务用户没有 sudo 权限本身是合理的安全设计。
例如:
useradd --system --create-home hermes
su - hermes
这种用户适合长期运行服务,但不应该被假设能安装系统包。
问题在于安装脚本没有在 Playwright 步骤前充分判断:
当前环境是否能无交互地执行 sudo?
当前安装是否有 TTY?
浏览器工具是否必须安装?
如果失败,是否应继续完成核心安装?
对比:系统包安装通常会先检测 sudo -n true
issue 里提到,安装器其他步骤已经有类似的降级思路:先检查是否能无交互 sudo。
典型判断类似:
sudo -n true
含义是:
如果当前用户不能免密码 sudo,不要弹交互密码提示,直接失败返回。
这对 curl | bash、system service user、CI、无 TTY 环境尤其重要。
因为这些环境里,弹出:
[sudo] password for hermes:
通常没有实际意义,只会让进程挂住。
Playwright --with-deps 步骤也应该遵守类似原则:能无交互完成就执行;不能就给出清晰提示并跳过,而不是阻塞安装。
更合理的安装行为:浏览器依赖可选、失败不应中断核心安装
从 issue 的期望行为看,比较稳的处理方式是:
检测 sudo 能力
→ 如果不能无交互 sudo,则跳过 --with-deps
→ 打印手动安装说明
→ 继续 setup_path
→ 让 hermes doctor 可用
也就是说,安装器应优先保证核心命令可用:
hermes
hermes doctor
hermes gateway
hermes chat
浏览器相关工具可以处于“未安装浏览器引擎”的降级状态。
这样用户至少能完成后续诊断:
hermes doctor
并根据提示手动处理 Playwright:
npx playwright install chromium
# 或由管理员单独安装系统依赖
相比之下,当前卡在 setup_path() 之前,会让用户失去最重要的诊断入口。
交互式安装和非交互式安装应该区分
issue 中提出的修复方向之一,是在安装浏览器引擎前加一个交互式确认:
Install Playwright/Chromium browser engine? (Y/n)
这对有 TTY 的普通用户有帮助。
但对非交互式环境,更重要的是默认行为。
例如:
有 TTY:询问是否安装浏览器依赖
无 TTY:默认跳过可选浏览器依赖,并打印后续命令
没有 passwordless sudo:不进入 sudo password prompt
这类策略能覆盖:
curl | bash;- Docker build;
- CI;
- systemd service user;
- SSH 自动化安装;
- 无 sudo 权限的托管环境。
安装脚本的客观目标不是“尽量装完所有组件”,而是“不要把可选组件失败扩大成核心安装失败”。
为什么直接运行 raw entry point 会报 dotenv?
issue 里还有一个后续现象:安装中断后,用户尝试直接运行:
~/.hermes/hermes-agent/hermes
结果遇到:
ModuleNotFoundError: No module named 'dotenv'
这通常说明运行路径没有走安装器创建的 venv launcher。
正确的 launcher shim 会负责使用 Hermes 的虚拟环境 Python 和依赖路径。安装流程没走到 setup_path(),这个 shim 没创建,用户直接跑 raw entry point,就可能落到系统 Python。
所以这个 dotenv 错误不是第一根因,而是半安装状态的连锁结果。
排查时应先回到安装器中断点:
Playwright --with-deps sudo prompt
与重复 issue 和 PR 的关系
评论里维护者指出,#25816 与 #22152 属于同类问题:
installer hangs on sudo password prompt during Playwright --with-deps for non-sudo service users
并提到相关修复方向在 PR #25814 和 #23500 中处理。
这说明问题不只是单个用户环境,而是安装器对 Playwright 可选依赖处理方式需要收敛:
可选浏览器依赖不应阻塞核心 CLI 安装。
从 SEO 搜索角度看,用户通常不会搜 issue 号,而会搜这些具体症状:
Hermes installer hangs sudo password
Playwright --with-deps sudo prompt
Hermes install non-sudo user
No hermes command after install
ModuleNotFoundError dotenv hermes install
文章标题和结构围绕这些客观症状展开,比单纯复述 GitHub issue 更有帮助。
临时处理思路:先完成核心安装,再补浏览器依赖
如果已经卡在这个问题上,处理顺序可以是:
1. 不要把 ModuleNotFoundError: dotenv 当第一问题; 2. 确认安装是否停在 Playwright --with-deps; 3. 用有 sudo 权限的管理员安装系统依赖,或跳过浏览器依赖; 4. 重新执行安装,确保 setup_path() 完成; 5. 先让 hermes doctor 可用; 6. 再决定是否启用浏览器相关工具。
如果你的部署目标只是 Gateway、CLI chat、消息平台、模型调用,浏览器引擎未安装通常不应该阻止核心链路启动。
后续是否需要 Chromium,取决于你是否实际使用 browser / Playwright 类工具。
和模型 API 配置的边界
Hermes 部署链路里,安装器、CLI、Gateway、工具系统、模型 Provider 是不同层。
这个 issue 位于安装层:
installer → Node.js deps → Playwright browser deps → setup_path
如果你安装完成后,还要接 OpenAI-compatible 模型服务或 DeepAI API 中转站,那通常是后面的模型调用层配置:
Base URL: https://api.deepai.wang/v1
API Key
model id
streaming / timeout / usage
分层看问题会更清楚:安装器是否完成、hermes 命令是否可用,先由本机安装流程决定;模型调用是否成功,再看 provider 和 API 网关配置。
FAQ
为什么 npx playwright install --with-deps chromium 会要 sudo?
因为 --with-deps 不只安装浏览器二进制,还可能安装系统共享库依赖。在 Debian / Ubuntu 上,这通常需要 apt 和 root 权限。
非 sudo 服务用户安装 Hermes 合理吗?
合理。服务用户低权限运行是常见安全实践。安装器应该识别这种环境,并对可选步骤降级处理。
为什么安装中断后没有 hermes doctor?
因为 Playwright 步骤发生在 setup_path() 之前。安装卡住时,launcher shim 还没创建,hermes 命令不可用。
ModuleNotFoundError: No module named 'dotenv' 是根因吗?
通常不是。它更像半安装后直接运行 raw entry point 导致绕过 venv 的结果。应先处理安装流程没有完成的问题。
浏览器工具必须安装吗?
不一定。Playwright / Chromium 主要影响浏览器相关能力。核心 CLI、Gateway、模型调用不应该因为可选浏览器依赖失败而无法完成安装。
总结
#25816 的本质是一个安装器健壮性问题:
可选的 Playwright browser dependency step
在非 sudo 用户下触发 sudo password prompt
并且发生在 setup_path 之前
导致安装进入半完成状态
更稳的安装器策略应该是:
检测 passwordless sudo
无权限时跳过可选浏览器依赖
打印手动安装说明
继续完成 setup_path
保证 hermes doctor 可用
这样即使浏览器工具暂时不可用,用户也能得到一个完整、可诊断、可继续配置的 Hermes 安装。