在本地 Docker 中运行 Hermes Agent,并在容器内安装 Hermes Web UI,实现一个容器同时提供 Gateway API 和 Web 管理界面。
环境要求
-
Docker Desktop 或 OrbStack
-
至少 4GB 可用内存
-
网络连接(拉取镜像)
架构说明
```
浏览器 → Web UI (:8648) → Gateway API (:8642) → AI 模型
同一个 Docker 容器内
```
所有组件运行在同一个容器中,Web UI 通过 `127.0.0.1:8642` 直连 Gateway,无需额外网络配置。
第一步:启动 Hermes 容器
拉取镜像并启动,映射三个端口:
```bash
docker run -d \
--name hermes \
--hostname hermes \
--restart unless-stopped \
--init \
-p 8642:8642 \
-p 8648:8648 \
-p 9119:9119 \
-v ~/.hermes:/opt/data \
-e HERMES_DASHBOARD=1 \
-e PYTHONUNBUFFERED=1 \
-e HERMES_HOME=/opt/data \
nousresearch/hermes-agent:latest \
/usr/bin/tini -g -- /opt/hermes/docker/entrypoint.sh gateway run
```
| 端口 | 用途 |
|------|------|
| 8642 | Gateway API(模型对话接口) |
| 8648 | Web UI 管理界面 |
| 9119 | 内置 Dashboard |
> **注意**:`~/.hermes` 是数据持久化目录,配置文件、会话记录、凭证都存在这里。首次运行会自动创建。
验证容器是否正常:
```bash
docker logs -f hermes
```
看到 `Hermes Gateway Starting...` 表示启动成功。
第二步:配置 Gateway API Server
Hermes 默认不开启 API Server,Web UI 需要通过它来对话。编辑配置文件:
```bash
docker exec hermes bash -c 'cat >> /opt/data/config.yaml << "EOF"
platforms:
api_server:
extra:
port: 8642
host: 127.0.0.1
enabled: true
key: ""
cors_origins: "*"
EOF'
```
> **重要**:`host` 必须是 `127.0.0.1`,不能是 `0.0.0.0`。绑定 `0.0.0.0` 需要设置 `API_SERVER_KEY`,否则 Gateway 会拒绝启动。
重启容器使配置生效:
```bash
docker restart hermes
```
验证 API Server 是否启动:
```bash
docker exec hermes bash -c 'apt-get install -y iproute2 > /dev/null 2>&1; ss -tlnp | grep 8642'
```
看到类似 `LISTEN ... 127.0.0.1:8642` 即为成功。
第三步:在容器内安装 Node.js
Hermes Web UI 需要 Node.js >= 23,但容器自带的是 Node 20。通过 nvm 安装:
```bash
安装 nvm
docker exec hermes bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash'
安装 Node 23
docker exec hermes bash -c 'export NVM_DIR="HOME/.nvm" \&\& source "NVM_DIR/nvm.sh" && nvm install 23'
写入 .bashrc 使其持久化(容器重启后仍可用)
docker exec hermes bash -c 'grep -q "nvm.sh" /root/.bashrc || cat >> /root/.bashrc << "EOF"
export NVM_DIR="$HOME/.nvm"
-s "$NVM_DIR/nvm.sh" \] \&\& . "$NVM_DIR/nvm.sh" \[ -s "$NVM_DIR/bash_completion" \] \&\& . "$NVM_DIR/bash_completion" EOF' \`\`\` --- ## 第四步:安装 Hermes Web UI \`\`\`bash docker exec hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& npm install -g hermes-web-ui' \`\`\` 启动 Web UI: \`\`\`bash docker exec -d hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& export PATH="/opt/hermes/.venv/bin:$PATH" \&\& export HERMES_BIN="/opt/hermes/.venv/bin/hermes" \&\& hermes-web-ui start' \`\`\` \> \*\*关键\*\*:必须把 \`/opt/hermes/.venv/bin\` 加入 \`PATH\` 并设置 \`HERMES_BIN\`,否则 Web UI 找不到 \`hermes\` CLI,会出现 \`spawn hermes ENOENT\` 错误。 --- ## 第五步:访问 Web UI 打开浏览器访问 \*\*http://localhost:8648\*\*。 首次访问需要输入 Auth Token,从日志中获取: \`\`\`bash docker exec hermes cat /root/.hermes-web-ui/logs/server.log \| grep "Auth enabled" \`\`\` 输出类似: \`\`\` Auth enabled --- token: 44fe2e7c7f40923606127176fbb78a2222a45598f4a7d2bd010cfeeb3c3ae2a4 \`\`\` 复制 token 填入登录页面即可。 --- ## 常用管理命令 \`\`\`bash # 查看 Web UI 状态 docker exec hermes bash -lc 'hermes-web-ui status' # 停止 Web UI docker exec hermes bash -lc 'hermes-web-ui stop' # 重启 Web UI docker exec hermes bash -lc 'hermes-web-ui stop' docker exec -d hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& export PATH="/opt/hermes/.venv/bin:$PATH" \&\& export HERMES_BIN="/opt/hermes/.venv/bin/hermes" \&\& hermes-web-ui start' # 查看 Web UI 日志 docker exec hermes cat /root/.hermes-web-ui/logs/server.log # 更新 Web UI 到最新版 docker exec hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& npm update -g hermes-web-ui' # 查看 Gateway 日志 docker logs hermes \`\`\` --- ## 配置 AI 模型 Web UI 启动后,需要配置至少一个模型才能对话。编辑凭证文件: \`\`\`bash # 进入容器编辑 auth.json docker exec -it hermes bash -c 'cat /opt/data/auth.json' \`\`\` 如果没有该文件,在 Web UI 的 \*\*Settings → Model Settings\*\* 页面中添加 Provider(如 OpenAI 兼容接口): 1. 填写 Provider 名称和 API Base URL 2. 填写 API Key 3. 点击 Fetch Models 获取可用模型列表 4. 选择默认模型 也可以直接编辑 \`\~/.hermes/auth.json\`(宿主机路径),格式参考 Hermes 官方文档。 --- ## 容器重启后自动恢复 由于 nvm 和 npm 全局包安装在容器的临时文件系统中,\*\*容器重建后需要重新执行第三步和第四步\*\*。如果只是 \`docker restart\`,数据不会丢失。 为了避免每次重建后手动操作,可以创建一个启动脚本: \`\`\`bash #!/bin/bash # save as: hermes-setup.sh echo "Installing nvm + Node 23..." docker exec hermes bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh \| bash' docker exec hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& nvm install 23' echo "Installing hermes-web-ui..." docker exec hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& npm install -g hermes-web-ui' echo "Configuring bashrc..." docker exec hermes bash -c 'grep -q "nvm.sh" /root/.bashrc \|\| cat \>\> /root/.bashrc \<\< "EOF" export NVM_DIR="$HOME/.nvm" \[ -s "$NVM_DIR/nvm.sh" \] \&\& . "$NVM_DIR/nvm.sh" \[ -s "$NVM_DIR/bash_completion" \] \&\& . "$NVM_DIR/bash_completion" EOF' echo "Starting hermes-web-ui..." docker exec -d hermes bash -c 'export NVM_DIR="$HOME/.nvm" \&\& source "$NVM_DIR/nvm.sh" \&\& export PATH="/opt/hermes/.venv/bin:$PATH" \&\& export HERMES_BIN="/opt/hermes/.venv/bin/hermes" \&\& hermes-web-ui start' echo "Done! Access http://localhost:8648" \`\`\` --- ## 故障排查 \| 问题 \| 原因 \| 解决方案 \| \|------\|------\|----------\| \| \`spawn hermes ENOENT\` \| Web UI 找不到 hermes CLI \| 启动时设置 \`PATH\` 和 \`HERMES_BIN\` \| \| \`EBADENGINE node \>= 23\` \| 容器自带 Node 20 \| 通过 nvm 安装 Node 23 \| \| \`Refusing to start: binding to 0.0.0.0\` \| API Server 绑定公网需要 Key \| 改为 \`host: 127.0.0.1\` \| \| Socket.IO 连接失败 \| Gateway 没有启动 API Server \| 添加 \`platforms.api_server\` 配置 \| \| 端口被占用 \| 宿主机端口冲突 \| 更换 \`-p\` 映射端口 \| \| 容器重建后丢失 nvm \| nvm 在临时文件系统中 \| 重新执行安装脚本或制作自定义镜像 \| --- ## 参考链接 - Hermes Agent:https://github.com/nousresearch/hermes-agent - Hermes Web UI:https://github.com/EKKOLearnAI/hermes-web-ui