Files
2026-06-14 14:30:48 -04:00

614 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
sidebar_position: 7
title: "Docker"
description: "在 Docker 中运行 Hermes Agent 以及将 Docker 用作终端后端"
---
# Hermes Agent — Docker
Docker 与 Hermes Agent 的交集有两种截然不同的方式:
1. **在 Docker 中运行 Hermes** — agent 本身在容器内运行(本页的主要内容)
2. **Docker 作为终端后端** — agent 在宿主机上运行,但将每条命令在单个持久化 Docker 沙箱容器中执行,该容器在工具调用、`/new` 和子 agent 之间保持存活,直至 Hermes 进程结束(参见 [配置 → Docker 后端](./configuration.md#docker-backend)
本页介绍选项 1。容器将所有用户数据(配置、API 密钥、会话、技能、记忆)存储在从宿主机挂载于 `/opt/data` 的单个目录中。镜像本身是无状态的,可通过拉取新版本进行升级而不会丢失任何配置。
## 快速开始
如果这是你第一次运行 Hermes Agent,请在宿主机上创建一个数据目录,并以交互方式启动容器以运行设置向导:
```sh
mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setup
```
这将进入设置向导,向导会提示你输入 API 密钥并将其写入 `~/.hermes/.env`。你只需执行一次。强烈建议此时为 gateway 配置一个聊天系统。
## 以 gateway 模式运行
配置完成后,将容器作为持久化 gatewayTelegram、Discord、Slack、WhatsApp 等)在后台运行:
```sh
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
```
端口 8642 暴露 gateway 的 [OpenAI 兼容 API 服务器](./features/api-server.md)和健康检查端点。如果你只使用聊天平台(Telegram、Discord 等),该端口是可选的;但如果你希望 dashboard 或外部工具访问 gateway,则必须开放。
注意:API 服务器需设置 `API_SERVER_ENABLED=true` 才会启用。若要在容器内将其暴露至 `127.0.0.1` 以外,还需设置 `API_SERVER_HOST=0.0.0.0``API_SERVER_KEY`(最少 8 个字符——可用 `openssl rand -hex 32` 生成)。示例:
```sh
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
-e API_SERVER_ENABLED=true \
-e API_SERVER_HOST=0.0.0.0 \
-e API_SERVER_KEY="$(openssl rand -hex 32)" \
-e API_SERVER_CORS_ORIGINS='*' \
nousresearch/hermes-agent gateway run
```
在面向互联网的机器上开放任何端口都存在安全风险。除非你了解相关风险,否则不应这样做。
## 运行 dashboard
内置 Web dashboard 作为可选的子进程在与 gateway 相同的容器内运行。设置 `HERMES_DASHBOARD=1` 可在容器回环地址(`127.0.0.1`)上默认运行 dashboard
```sh
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
-e HERMES_DASHBOARD=1 \
nousresearch/hermes-agent gateway run
```
入口点在 `exec` 主命令之前,以非 root 用户 `hermes` 在后台启动 `hermes dashboard`。Dashboard 输出在 `docker logs` 中以 `[dashboard]` 为前缀,便于与 gateway 日志区分。
| 环境变量 | 描述 | 默认值 |
|---------------------|-------------|---------|
| `HERMES_DASHBOARD` | 设为 `1`(或 `true` / `yes`)以在主命令旁启动 dashboard | *(未设置——不启动 dashboard)* |
| `HERMES_DASHBOARD_HOST` | dashboard HTTP 服务器的绑定地址 | `127.0.0.1` |
| `HERMES_DASHBOARD_PORT` | dashboard HTTP 服务器的端口 | `9119` |
| `HERMES_DASHBOARD_INSECURE` | 设为 `1`(或 `true` / `yes`)以在不启用 OAuth 鉴权门控的情况下绑定。仅在可信网络(且通过没有 OAuth 契约的反向代理时)使用——dashboard 会暴露 API 密钥与会话数据 | *(未设置——当注册了 `DashboardAuthProvider` 时启用门控)* |
默认情况下,dashboard 保持在回环地址(`127.0.0.1`),以避免将
Web 界面暴露到网络。若要有意发布,请设置
`HERMES_DASHBOARD_HOST=0.0.0.0`。当以下两项同时满足时,
dashboard 的 OAuth 鉴权门控会自动启用:
1. 绑定地址为非回环地址,**且**
2. 注册了一个 `DashboardAuthProvider` 插件。
捆绑的 `dashboard_auth/nous` 提供者会在设置
`HERMES_DASHBOARD_OAUTH_CLIENT_ID` 时自动激活(参见
[Web Dashboard → 鉴权](features/web-dashboard.md))。门控启用后,
浏览器调用方会先被重定向到所配置门户的 OAuth 流,然后才能
访问任何受保护路由。
如果未注册提供者且绑定为非回环地址,dashboard **会在启动时
失败关闭**,并给出指向缺失环境变量的具体错误信息。要显式
退出门控——用于不使用 OAuth 契约、通过你自己的反向代理部署
在可信局域网中的场景——请设置 `HERMES_DASHBOARD_INSECURE=1`
这会恢复旧的“无鉴权,但发出告警”模式,也是唯一可以禁用门控的
路径;绑定地址不再隐式决定 `--insecure`
:::note
dashboard 在容器内作为受监管的 s6 服务运行。如果
dashboard 进程崩溃,s6-overlay 会在短暂退避后自动
重启它——你会看到新的 PID,无需重启容器。日志和崩溃输出可通过
`docker logs <container>` 查看(s6 将服务的 stdout/stderr 转发至此)。
当独立的 dashboard 容器与宿主机共享 PID 与网络命名空间时(例如 `network_mode: host`,正如仓库自带的 `docker-compose.yml` 中的 `dashboard` 服务那样),**是**支持将 dashboard 作为独立容器运行的。其 gateway 存活检测需要与 gateway 进程共享 PID 命名空间,因此该限制仅适用于在隔离的 bridge 网络容器中、且未共享 PID 命名空间的 dashboard。
:::
## 交互式运行(CLI 聊天)
对已有数据目录打开交互式聊天会话:
```sh
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent
```
或者,如果你已通过 Docker Desktop 等方式在运行中的容器内打开了终端,直接运行:
```sh
/opt/hermes/.venv/bin/hermes
```
## 持久化卷
`/opt/data` 卷是所有 Hermes 状态的唯一数据来源。它映射到宿主机的 `~/.hermes/` 目录,包含:
| 路径 | 内容 |
|------|----------|
| `.env` | API 密钥和机密 |
| `config.yaml` | 所有 Hermes 配置 |
| `SOUL.md` | Agent 个性/身份 |
| `sessions/` | 对话历史 |
| `memories/` | 持久化记忆存储 |
| `skills/` | 已安装的技能 |
| `cron/` | 定时任务定义 |
| `hooks/` | 事件 hook |
| `logs/` | 运行时日志 |
| `skins/` | 自定义 CLI 皮肤 |
:::warning
切勿同时对同一数据目录运行两个 Hermes **gateway** 容器——会话文件和记忆存储不支持并发写入。
:::
## 多 profile 支持
Hermes 支持[多个 profile](../reference/profile-commands.md)——独立的 `~/.hermes/` 目录,让你可以从单个安装运行独立的 agent(不同的 SOUL、技能、记忆、会话、凭据)。**在 Docker 下运行时,不建议使用 Hermes 内置的多 profile 功能。**
推荐的模式是**每个 profile 一个容器**,每个容器将各自的宿主机目录绑定挂载为 `/opt/data`
```sh
# 工作 profile
docker run -d \
--name hermes-work \
--restart unless-stopped \
-v ~/.hermes-work:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
# 个人 profile
docker run -d \
--name hermes-personal \
--restart unless-stopped \
-v ~/.hermes-personal:/opt/data \
-p 8643:8642 \
nousresearch/hermes-agent gateway run
```
在 Docker 中使用独立容器而非 profile 的原因:
- **隔离性** — 每个容器有独立的文件系统、进程表和资源限制。一个 profile 中的崩溃、依赖变更或失控会话不会影响另一个。
- **独立生命周期** — 可独立升级、重启、暂停或回滚每个 agent(`docker restart hermes-work` 不会影响 `hermes-personal`)。
- **清晰的端口和网络隔离** — 每个 gateway 绑定各自的宿主机端口;聊天平台或 API 服务器之间不存在串扰风险。
- **更简单的心智模型** — 容器即 profile。备份、迁移和权限管理都跟随绑定挂载的目录,无需记住额外的 `--profile` 标志。
- **避免并发写入风险** — 上述关于不得对同一数据目录运行两个 gateway 的警告同样适用于单个容器内的 profile。
在 Docker Compose 中,只需为每个 profile 声明一个服务,使用不同的 `container_name``volumes``ports`
```yaml
services:
hermes-work:
image: nousresearch/hermes-agent:latest
container_name: hermes-work
restart: unless-stopped
command: gateway run
ports:
- "8642:8642"
volumes:
- ~/.hermes-work:/opt/data
hermes-personal:
image: nousresearch/hermes-agent:latest
container_name: hermes-personal
restart: unless-stopped
command: gateway run
ports:
- "8643:8642"
volumes:
- ~/.hermes-personal:/opt/data
```
## 环境变量转发
API 密钥从容器内的 `/opt/data/.env` 读取。你也可以直接传递环境变量:
```sh
docker run -it --rm \
-v ~/.hermes:/opt/data \
-e ANTHROPIC_API_KEY="sk-ant-..." \
-e OPENAI_API_KEY="sk-..." \
nousresearch/hermes-agent
```
直接传入的 `-e` 标志会覆盖 `.env` 中的值。这对于不希望将密钥写入磁盘的 CI/CD 或密钥管理器集成非常有用。
:::note 寻找 Docker 作为**终端后端**的说明?
本页介绍在 Docker 内运行 Hermes 本身。如果你希望 Hermes 在 Docker 沙箱容器内执行 agent 的 `terminal` / `execute_code` 调用(每个 Hermes 进程对应一个持久容器),那是另一个配置块——`terminal.backend: docker` 加上 `terminal.docker_image``terminal.docker_volumes``terminal.docker_forward_env``terminal.docker_run_as_host_user``terminal.docker_extra_args`。完整配置请参见 [配置 → Docker 后端](configuration.md#docker-backend)。
:::
## Docker Compose 示例
对于同时运行 gateway 和 dashboard 的持久化部署,使用 `docker-compose.yaml` 更为方便:
```yaml
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "8642:8642" # gateway API
- "9119:9119" # dashboard(仅在 HERMES_DASHBOARD=1 时生效)
volumes:
- ~/.hermes:/opt/data
environment:
- HERMES_DASHBOARD=1
# 取消注释以直接转发特定环境变量而非使用 .env 文件:
# - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
# - OPENAI_API_KEY=${OPENAI_API_KEY}
# - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
```
使用 `docker compose up -d` 启动,使用 `docker compose logs -f` 查看日志。Dashboard 输出以 `[dashboard]` 为前缀,便于从 gateway 日志中过滤。
## 资源限制
Hermes 容器需要适量资源。推荐最低配置:
| 资源 | 最低 | 推荐 |
|----------|---------|-------------|
| 内存 | 1 GB | 24 GB |
| CPU | 1 核 | 2 核 |
| 磁盘(数据卷) | 500 MB | 2+ GB(随会话/技能增长) |
浏览器自动化(Playwright/Chromium)是最耗内存的功能。如果不需要浏览器工具,1 GB 即可。启用浏览器工具时,请至少分配 2 GB。
在 Docker 中设置限制:
```sh
docker run -d \
--name hermes \
--restart unless-stopped \
--memory=4g --cpus=2 \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
```
## Dockerfile 说明
官方镜像基于 `debian:13.4`,包含:
- Python 3 及所有 Hermes 依赖(`uv pip install -e ".[all]"`
- Node.js + npm(用于浏览器自动化和 WhatsApp 桥接)
- Playwright 与 Chromium`npx playwright install --with-deps chromium --only-shell`
- ripgrep、ffmpeg、git 和 `xz-utils` 作为系统工具
- **`docker-cli`** — 使容器内运行的 agent 可以驱动宿主机的 Docker 守护进程(绑定挂载 `/var/run/docker.sock` 以启用),用于 `docker build``docker run`、容器检查等操作
- **`openssh-client`** — 从容器内启用 [SSH 终端后端](/user-guide/configuration#ssh-backend)。SSH 后端调用系统 `ssh` 二进制文件;若缺少此组件,在容器化安装中会静默失败
- WhatsApp 桥接(`scripts/whatsapp-bridge/`
- **[`s6-overlay`](https://github.com/just-containers/s6-overlay) v3** 作为 PID 1(替代旧版 `tini`)——监管 dashboard 和各 profile gateway,崩溃后自动重启,回收僵尸子进程,并转发信号
容器的 `ENTRYPOINT` 是 s6-overlay 的 `/init`。启动时:
1. 以 root 身份运行 `/etc/cont-init.d/01-hermes-setup`(即 `docker/stage2-hook.sh`):可选的 UID/GID 重映射、修复卷所有权、首次启动时初始化 `.env` / `config.yaml` / `SOUL.md`、同步内置技能。
2. 运行 `/etc/cont-init.d/02-reconcile-profiles`(即 `hermes_cli.container_boot`):遍历 `$HERMES_HOME/profiles/<name>/`,在 `/run/service/gateway-<profile>/` 下重建各 profile 的 gateway s6 服务槽,并仅自动启动上次记录状态为 `running` 的 profile(参见 [Per-profile gateway 监管](#per-profile-gateway-supervision))。
3. 启动静态的 `main-hermes``dashboard` s6-rc 服务。
4. 将容器的 CMD 作为主程序 exec(`/opt/hermes/docker/main-wrapper.sh`),根据用户传给 `docker run` 的参数进行路由:
- 无参数 → `hermes`(默认)
- 第一个参数是 PATH 上的可执行文件(如 `sleep``bash`)→ 直接 exec
- 其他情况 → `hermes <args>`(子命令透传)
主程序退出时容器退出,并使用其退出码。
:::warning 与 pre-s6 镜像的破坏性变更
容器 ENTRYPOINT 现在是 `/init`s6-overlay),而非 `/usr/bin/tini`。所有五种已记录的 `docker run` 调用模式(无参数、`chat -q "…"``sleep infinity``bash``--tui`)的行为与基于 tini 的镜像完全相同。如果你有依赖 tini 特定信号行为或硬编码 `/usr/bin/tini --` 调用的下游封装,请固定到之前的镜像标签。
:::
:::warning 权限模型
除非你在命令链中保留 `/init`(或等效的旧版 `docker/entrypoint.sh` shim,它会转发到 stage2 hook),否则不要覆盖镜像入口点。s6-overlay 的 `/init` 以 root 运行,以便在首次启动时对卷执行 chown,然后通过 `s6-setuidgid` 为每个受监管的服务**以及**主程序降权至 `hermes` 用户。在官方镜像内以 root 启动 `hermes gateway run` 默认会被拒绝,因为这可能在 `/opt/data` 中留下 root 所有的文件,导致后续 dashboard 或 gateway 启动失败。仅在你有意接受该风险时才设置 `HERMES_ALLOW_ROOT_GATEWAY=1`
:::
### Per-profile gateway 监管
在容器内,每个通过 `hermes profile create <name>` 创建的 profile 都会自动在 `/run/service/gateway-<name>/` 注册一个受 s6 监管的 gateway 服务。你在宿主机上运行的生命周期命令在此同样适用:
```sh
hermes profile create coder # 注册 gateway-coder s6 槽
hermes -p coder gateway start # s6-svc -u → 受监管的 gateway
hermes -p coder gateway stop # s6-svc -d → 服务停止
hermes -p coder gateway restart # s6-svc -t → 向 supervisor 发送 SIGTERM
hermes profile delete coder # 拆除 s6 槽
```
**相比 pre-s6 镜像的监管优势:**
- Gateway 崩溃后由 `s6-supervise` 在约 1 秒退避后自动重启。
- Dashboard 崩溃后自动重启(设置 `HERMES_DASHBOARD=1` 以启动)。
- `docker restart` 保留运行中的 gatewaycont-init 协调器读取 `$HERMES_HOME/profiles/<name>/gateway_state.json`,若上次记录状态为 `running` 则恢复该槽。已停止的 gateway 保持停止状态。
- 各 profile 的 gateway 日志持久化于 `$HERMES_HOME/logs/gateways/<profile>/current`(由 `s6-log` 轮转),协调器的操作记录在每次启动时追加到 `$HERMES_HOME/logs/container-boot.log`
在容器内执行 `hermes status` 会显示 `Manager: s6 (container supervisor)`。使用 `/command/s6-svstat /run/service/gateway-<name>` 查看原始 supervisor 状态(注意 `/command/` 仅在监管树进程的 PATH 中;从 `docker exec` 调用时请传入绝对路径)。
## 升级
拉取最新镜像并重建容器。你的数据目录不受影响。
```sh
docker pull nousresearch/hermes-agent:latest
docker rm -f hermes
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
```
或使用 Docker Compose
```sh
docker compose pull
docker compose up -d
```
## 技能与凭据文件
当使用 Docker 作为执行环境时(不是上述方法,而是 agent 在 Docker 沙箱内运行命令——参见 [配置 → Docker 后端](./configuration.md#docker-backend)),Hermes 为所有工具调用复用单个长期运行的容器,并自动将技能目录(`~/.hermes/skills/`)和技能声明的所有凭据文件以只读卷的形式绑定挂载到该容器中。技能脚本、模板和引用在沙箱内无需手动配置即可使用,由于容器在 Hermes 进程的整个生命周期内持续存在,你安装的任何依赖或写入的文件都会在下次工具调用时保留。
SSH 和 Modal 后端也会进行相同的同步——技能和凭据文件在每次命令执行前通过 rsync 或 Modal mount API 上传。
## 在容器中安装更多工具
官方镜像预装了一套精选工具(参见 [Dockerfile 说明](#what-the-dockerfile-does)),但并非 agent 可能需要的每个工具都已预装。以下是五种推荐方式,按工作量和持久性递增排列。
### npm 或 Python 工具——使用 `npx` 或 `uvx`
对于发布到 npm 或 PyPI 的任何工具,指示 Hermes 通过 `npx`npm)或 `uvx`(Python)运行,并将该命令记入其持久记忆。如果工具需要配置文件或凭据,指示其将这些文件放在 `/opt/data` 下(如 `/opt/data/<tool>/config.yaml`)。
依赖按需获取并在容器生命周期内缓存。写入 `/opt/data` 的配置在容器重启后仍然存在,因为它位于绑定挂载的宿主机目录上。包缓存本身在 `docker rm` 后会重建,但 `npx``uvx` 会在下次运行工具时透明地重新获取。
### 其他工具(apt 包、二进制文件)——安装并记住
对于 npm 或 PyPI 之外的工具——`apt` 包、预构建二进制文件、镜像中未包含的语言运行时——指示 Hermes 如何安装(如 `apt-get update && apt-get install -y <package>`),并告知它记住该安装命令。工具在容器剩余生命周期内持续可用,Hermes 在容器重启后下次需要该工具时会重新运行安装命令。
这种方式适合安装快速且偶尔使用的工具。对于频繁使用的工具,建议采用下一种方式。
### 持久安装——构建派生镜像
当工具必须在每次容器启动时立即可用且无需重新安装延迟时,构建一个继承自 `nousresearch/hermes-agent` 并在层中安装该工具的新镜像:
```dockerfile
FROM nousresearch/hermes-agent:latest
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends <your-package> \
&& rm -rf /var/lib/apt/lists/*
USER hermes
```
构建并替换官方镜像使用:
```sh
docker build -t my-hermes:latest .
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
my-hermes:latest gateway run
```
入口点脚本和 `/opt/data` 语义原样继承,本页其余内容仍然适用。拉取更新的上游 `nousresearch/hermes-agent` 时记得重新构建镜像。
### 复杂工具或多服务栈——运行 sidecar 容器
对于自带服务(数据库、Web 服务器、队列、无头浏览器集群)或过于庞大而不适合放在 Hermes 容器内的工具,将其作为独立容器运行在共享 Docker 网络上。Hermes 通过容器名称访问 sidecar,与访问本地推理服务器的方式相同(参见 [连接本地推理服务器](#connecting-to-local-inference-servers-vllm-ollama-etc))。
```yaml
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
networks:
- hermes-net
my-tool:
image: example/my-tool:latest
container_name: my-tool
restart: unless-stopped
networks:
- hermes-net
networks:
hermes-net:
driver: bridge
```
在 Hermes 容器内,sidecar 可通过 `http://my-tool:<port>` 访问(或其提供的任何协议)。这种模式使每个服务的生命周期、资源限制和升级节奏保持独立,避免因单个工具的依赖而使 Hermes 镜像臃肿。
### 广泛有用的工具——提交 issue 或 pull request
如果某个工具可能对大多数 Hermes Agent 用户有用,考虑将其贡献到上游,而不是在私有派生镜像中维护。在 [hermes-agent 仓库](https://github.com/NousResearch/hermes-agent)提交 issue 或 pull request,描述该工具及其使用场景。被纳入官方镜像的工具惠及所有用户,并避免了维护下游 fork 的开销。
## 连接本地推理服务器(vLLM、Ollama 等)
在 Docker 中运行 Hermes 且推理服务器(vLLM、Ollama、text-generation-inference 等)也在宿主机或另一个容器中运行时,网络配置需要额外注意。
### Docker Compose(推荐)
将两个服务放在同一 Docker 网络上。这是最可靠的方式:
```yaml
services:
vllm:
image: vllm/vllm-openai:latest
container_name: vllm
command: >
--model Qwen/Qwen2.5-7B-Instruct
--served-model-name my-model
--host 0.0.0.0
--port 8000
ports:
- "8000:8000"
networks:
- hermes-net
deploy:
resources:
reservations:
devices:
- capabilities: [gpu]
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "8642:8642"
volumes:
- ~/.hermes:/opt/data
networks:
- hermes-net
networks:
hermes-net:
driver: bridge
```
然后在 `~/.hermes/config.yaml` 中,使用**容器名称**作为主机名:
```yaml
model:
provider: custom
model: my-model
base_url: http://vllm:8000/v1
api_key: "none"
```
:::tip 关键点
- 使用**容器名称**`vllm`)作为主机名——而非 `localhost``127.0.0.1`,它们指向 Hermes 容器本身。
- `model` 值必须与传给 vLLM 的 `--served-model-name` 一致。
-`api_key` 设为任意非空字符串(vLLM 要求该请求头,但默认不验证其值)。
- `base_url` 末尾**不要**加斜杠。
:::
### 独立 Docker run(无 Compose
如果推理服务器直接在宿主机上运行(不在 Docker 中),在 macOS/Windows 上使用 `host.docker.internal`,在 Linux 上使用 `--network host`
**macOS / Windows**
```sh
docker run -d \
--name hermes \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
```
```yaml
# config.yaml
model:
provider: custom
model: my-model
base_url: http://host.docker.internal:8000/v1
api_key: "none"
```
**Linuxhost 网络):**
```sh
docker run -d \
--name hermes \
--network host \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
```
```yaml
# config.yaml
model:
provider: custom
model: my-model
base_url: http://127.0.0.1:8000/v1
api_key: "none"
```
:::warning 使用 `--network host` 时,`-p` 标志会被忽略——所有容器端口直接暴露在宿主机上。
:::
### 验证连通性
从 Hermes 容器内部确认推理服务器可达:
```sh
docker exec hermes curl -s http://vllm:8000/v1/models
```
你应该看到列出已服务模型的 JSON 响应。如果失败,请检查:
1. 两个容器是否在同一 Docker 网络上(`docker network inspect hermes-net`
2. 推理服务器是否监听 `0.0.0.0` 而非 `127.0.0.1`
3. 端口号是否匹配
### Ollama
Ollama 的配置方式相同。如果 Ollama 在宿主机上运行,使用 `host.docker.internal:11434`macOS/Windows)或 `127.0.0.1:11434`Linux 使用 `--network host`)。如果 Ollama 在同一 Docker 网络的独立容器中运行:
```yaml
model:
provider: custom
model: llama3
base_url: http://ollama:11434/v1
api_key: "none"
```
## 故障排查
### 容器立即退出
检查日志:`docker logs hermes`。常见原因:
- `.env` 文件缺失或无效——先以交互方式运行以完成设置
- 开放端口时存在端口冲突
### "Permission denied" 错误
容器的 stage2 hook 通过 `s6-setuidgid` 在每个受监管的服务内将权限降至非 root 用户 `hermes`UID 10000)。如果宿主机的 `~/.hermes/` 由不同 UID 拥有,请设置 `HERMES_UID`/`HERMES_GID` 以匹配宿主机用户,或确保数据目录可写:
```sh
chmod -R 755 ~/.hermes
```
### 浏览器工具无法使用
Playwright 需要共享内存。在 Docker run 命令中添加 `--shm-size=1g`
```sh
docker run -d \
--name hermes \
--shm-size=1g \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
```
### 网络问题后 gateway 无法重连
`--restart unless-stopped` 标志可处理大多数瞬时故障。如果 gateway 卡住,重启容器:
```sh
docker restart hermes
```
### 检查容器健康状态
```sh
docker logs --tail 50 hermes # 最近日志
docker run -it --rm nousresearch/hermes-agent:latest version # 验证版本
docker stats hermes # 资源使用情况
```