明明在宿主机,却被 Hermes 误判为 Docker 容器?一个 stamp 文件引发的血案!


🎯 问题现象

今天在宿主机执行 hermes update --check,结果跳出了 Docker 相关的提示:

1
2
3
4
5
6
7
✗ ``hermes update`` doesn't apply inside the Docker container.

Hermes Agent runs as a published image (nousresearch/hermes-agent), not a
git checkout — the container has no working tree to pull into. Update by
pulling a fresh image and restarting your container instead:

docker pull nousresearch/hermes-agent:latest

但我明明是在 macOS 宿主机上,根本没在 Docker 容器里。


🔍 背景

我确实拉过 Hermes 的 Docker image,但那是为了测试用,打算把 Docker 的配置放在 ~/.hermes-docker/ 里,和宿主机的 ~/.hermes/ 分开。


🔧 排查过程

第一步:确认环境

先看看系统到底检测到了什么:

1
2
3
4
5
6
7
$ ls -la /.dockerenv
no /.dockerenv

$ env | grep -i docker
TERMINAL_DOCKER_IMAGE=nikolaik/python-nodejs:python3.11-nodejs20
TERMINAL_DOCKER_ENV={}
TERMINAL_DOCKER_VOLUMES=[]

环境里确实有 TERMINAL_DOCKER_* 变量,但这些是 终端工具的配置,不是 Docker 容器本身的标志。

第二步:定位检测逻辑

Hermes 的更新命令在 hermes_cli/main.py 里,检测逻辑在 hermes_cli/config.py

1
2
3
4
5
6
7
8
9
10
def detect_install_method(project_root: Optional[Path] = None) -> str:
"""Detect how Hermes was installed: 'docker', 'nixos', 'homebrew', 'git', or 'pip'."""
stamp = get_hermes_home() / ".install_method"
try:
method = stamp.read_text(encoding="utf-8").strip().lower()
if method:
return method
except OSError:
pass
# ... 后续检查 HERMES_MANAGED、.git 目录等

关键点:检测顺序是:

  1. ~/.hermes/.install_method stamp 文件(优先级最高)
  2. HERMES_MANAGED 环境变量 / .managed 标记文件
  3. .git 目录是否存在
  4. fallback 到 pip

第三步:检查 stamp 文件

1
2
$ cat ~/.hermes/.install_method
docker

找到问题了! stamp 文件里写的是 docker,但我的实际安装方式是 git clone

检查一下 git 目录:

1
2
$ test -d ~/.hermes/hermes-agent/.git && echo "IS_GIT" || echo "NOT_GIT"
IS_GIT

确认是 git 安装,但 stamp 文件内容不对。


⚡ 根本原因

~/.hermes/.install_method 这个文件是在安装/初始化时写入的,用来标记安装方式。

我的情况是:之前可能用 Docker 跑过 Hermes,而 Docker 容器启动时通过 docker/stage2-hook.sh 写入了 docker 到 stamp 文件。后来虽然改用宿主机 git 安装,但这个 stamp 文件没被更新。

Hermes 的检测逻辑设计

  • 不依赖容器环境检测(如 /.dockerenv),因为手动安装到容器里的情况无法区分
  • 完全信任 .install_method stamp 文件
  • Docker image 会在启动时自动 stamp 为 docker
  • curl 安装脚本会 stamp 为 git

所以问题就是:stamp 文件内容与实际安装方式不匹配


✅ 解决方案

直接修改 stamp 文件:

1
$ echo "git" > ~/.hermes/.install_method

验证:

1
2
3
4
5
$ hermes update --check
→ Fetching from upstream...
→ Fetching from origin...
⚕ Update available: 717 commits behind origin/main.
Run 'hermes update' to install.

恢复正常了。


📝 经验总结

  1. stamp 文件优先级最高~/.hermes/.install_method 的内容直接决定 detect_install_method() 的返回值,后续所有安装方式相关的判断都基于此。

  2. Docker 和宿主机共用 HERMES_HOME 会冲突:如果 Docker 容器和宿主机 mount 同一个 ~/.hermes 目录,stamp 文件会被互相覆盖。建议:

    • Docker 用 ~/.hermes-docker/-v ~/.hermes-docker:/opt/data
    • 宿主机用 ~/.hermes/
  3. 环境变量误导TERMINAL_DOCKER_* 是终端工具的 Docker 后端配置,不是容器本身。Hermes 的检测逻辑没依赖这些变量,算是躲过一劫。

  4. 官方文档的说明

    running inside a container is NOT treated as “docker” on its own.
    The two supported install paths both self-identify via the .install_method stamp

    所以不要试图通过删环境变量来”骗”过检测,直接改 stamp 文件才是正道。


📚 参考资料


创建时间:2026-06-12 · 本文档由 Hermes 用户 🐧 自动排查并记录