☰
在 CentOS 7 的 Docker 环境部署 Hermes 三件套:TaoToken 统一 Key 接入与 docker-compose 验证
2026/10/20 4:50:29 网站建设 项目流程

1. CentOS 7 上跑 Hermes 三件套,为什么官方 compose 一上来就翻车

Hermes 三件套指的是 hermes-agent、hermes-webui、hermes-dashboard 三个容器:agent 负责网关 API(默认 8642 端口,承接 CLI、Telegram、cron、工具调用),webui 是浏览器聊天界面(8787),dashboard 用来监控会话和资源占用(9119)。这套东西适合想在自己服务器上搭一套私有 Agent 环境的人,尤其是手里只有 CentOS 7 老机器、又不想重装系统的场景。

但如果你直接把 webui 里导出的docker-compose.three-container.yml拿去up -d,大概率会遇到三种情况:容器起来了但 webui 打不开、agent 因为权限问题反复重启、局域网里其他机器访问不了。我试过在 CentOS 7.9 + Docker 20.10 上完整走一遍,踩的坑基本都集中在端口绑定、挂载目录权限、UID/GID 映射这三块。

CentOS 7 本身还有两个额外麻烦:一是默认内核 3.10,Docker 版本不能太新,20.10.x 是比较稳的选择;二是 SELinux 默认开启,挂载宿主机目录时如果不处理标签,容器里会报 Permission denied。所以这篇不是简单贴一份 compose 就完事,而是把「能跑起来」和「能验证跑通了」两件事都做完整,包括接入 TaoToken 统一 Key 的那一步。

下面按顺序来:先确认 CentOS 7 的 Docker 环境,再准备 TaoToken 的 Key 和 Base URL,然后给一份改好的 compose,接着启动并验证接口连通性,最后把几个高频报错逐个拆掉。

2. 前置准备:CentOS 7 的 Docker 环境与 TaoToken 统一 Key

2.1 CentOS 7 上的 Docker 与 compose 版本确认

CentOS 7 的 yum 源里 docker 版本偏旧,建议用官方仓库装 20.10。装完之后先确认两件事:

docker --version # 期望输出类似:Docker version 20.10.24, build 297e128 docker compose version # 期望输出类似:Docker Compose version v2.20.2

注意docker compose(带空格,v2 插件)和docker-compose(带横线,v1 独立二进制)是两套命令。官方 compose 文件里写的是docker compose -f ...,如果你只有 v1,命令要换成docker-compose -f ...,其余参数一致。CentOS 7 上如果docker compose version报错,说明插件没装,可以单独装 compose v2 二进制到/usr/local/lib/docker/cli-plugins/。

SELinux 这块,如果你不想折腾标签,最省事的做法是给挂载目录打上容器可读标签:

sudo mkdir -p /data/hermes/home /data/hermes/workspace sudo chcon -Rt svirt_sandbox_file_t /data/hermes

这一步不做的话,后面容器里写/home/hermes/.hermes会直接失败,日志里是Permission denied,很容易误判成 UID 问题。

2.2 TaoToken 统一 Key 的获取与 Base URL

Hermes agent 要调用大模型,需要三个东西:Base URL、API Key、Model ID。TaoToken 在这里的作用是把多家模型的调用收敛成一个统一入口,你只需要一个 Key 就能在 agent 里切换模型,不用为每个模型单独配一套凭证。

获取 Key 的入口在控制台的 API Keys 页面:

https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite

创建之后复制出来,形如sk-xxxxxxxx。Base URL 统一用:

https://taotoken.net/api

注意这个地址后面不要加 UTM 参数,直接作为 API 端点写进配置。Model ID 按你实际要用的填,比如claude-sonnet-4-5这类,具体以模型对话页面里列出的为准:

https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite

如果你后面要长期跑 coding agent 或者定时任务,可以看下 Coding Plan,额度模型和按量计费不太一样:

https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

接入文档在:

https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

把 Key、Base URL、Model ID 三件套先记下来,下一步写进.env文件。

3. 可复制的 docker-compose 配置与环境变量

3.1 目录结构与 .env 文件

先在宿主机建好目录,compose 文件和.env放在同一个工作目录,比如/data/hermes/deploy:

mkdir -p /data/hermes/deploy cd /data/hermes/deploy

.env文件内容如下,UID/GID 用id -u和id -g的真实值填。CentOS 7 上普通用户通常是 1000,但如果你用的是别的账号,一定要换成实际值:

echo "UID=$(id -u)" >> .env echo "GID=$(id -g)" >> .env

然后手动补上模型相关的变量:

UID=1000 GID=1000 TAOTOKEN_API_KEY=sk-你的真实key TAOTOKEN_BASE_URL=https://taotoken.net/api HERMES_MODEL=claude-sonnet-4-5

这里TAOTOKEN_BASE_URL不要带任何查询参数,就是干净的https://taotoken.net/api。

3.2 修改后的 docker-compose.three-container.yml

下面这份是在官方文件基础上改过的,改动点我在注释里标了。核心是三处:端口从127.0.0.1改成0.0.0.0、挂载目录换成宿主机自定义路径、HERMES_HOME从 root 目录改到 home 目录。

services: hermes-agent: image: docker.xuanyuan.run/nousresearch/hermes-agent:latest container_name: hermes-agent command: gateway run ports: # 改:0.0.0.0 让局域网可访问,只本机用可换回 127.0.0.1 - "0.0.0.0:8642:8642" volumes: # 改:挂到宿主机自定义目录,方便观察和测试 - /data/hermes/home:/home/hermes/.hermes - hermes-agent-src:/opt/hermes environment: # 改:原来是 root 目录,权限问题导致启动失败,改到 home - HERMES_HOME=/home/hermes/.hermes - TAOTOKEN_API_KEY=${TAOTOKEN_API_KEY} - TAOTOKEN_BASE_URL=${TAOTOKEN_BASE_URL} - HERMES_MODEL=${HERMES_MODEL} restart: unless-stopped deploy: resources: limits: memory: 4G cpus: "2.0" networks: - hermes-net hermes-dashboard: image: docker.xuanyuan.run/nousresearch/hermes-agent:latest container_name: hermes-dashboard command: dashboard --host 0.0.0.0 --insecure ports: - "0.0.0.0:9119:9119" volumes: - /data/hermes/home:/home/hermes/.hermes environment: - HERMES_HOME=/home/hermes/.hermes - GATEWAY_HEALTH_URL=http://hermes-agent:8642 depends_on: - hermes-agent restart: unless-stopped deploy: resources: limits: memory: 512M cpus: "0.5" networks: - hermes-net hermes-webui: image: ghcr.io/nesquena/hermes-webui:latest container_name: hermes-webui depends_on: - hermes-agent ports: - "0.0.0.0:8787:8787" volumes: - /data/hermes/home:/home/hermeswebui/.hermes - hermes-agent-src:/home/hermeswebui/.hermes/hermes-agent - /data/hermes/workspace:/workspace environment: - HERMES_WEBUI_HOST=0.0.0.0 - HERMES_WEBUI_PORT=8787 - HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui # 改:用 .env 里的真实 UID/GID,避免文件权限错乱 - WANTED_UID=${UID} - WANTED_GID=${GID} restart: unless-stopped networks: - hermes-net networks: hermes-net: driver: bridge volumes: hermes-agent-src:

几个关键点解释一下。hermes-agent-src这个命名卷是给 webui 用的,webui 启动时会执行uv pip install /home/hermeswebui/.hermes/hermes-agent,从 agent 源码卷里装依赖,所以这个卷必须存在且被 agent 先填充。GATEWAY_HEALTH_URL指向http://hermes-agent:8642,走的是 compose 内部网络,不用暴露到宿主机。

注意:WANTED_UID和WANTED_GID必须和宿主机/data/hermes/home的属主一致,否则 webui 写状态文件会失败。用ls -ln /data/hermes/home确认一下数字属主。

3.3 启动命令

在/data/hermes/deploy目录下执行:

docker compose -f docker-compose.three-container.yml up -d

如果你用的是 compose v1:

docker-compose -f docker-compose.three-container.yml up -d

启动后看容器状态:

docker compose -f docker-compose.three-container.yml ps

三个容器都应该是Up状态。agent 内存限制 4G,dashboard 512M,webui 没设限制,CentOS 7 机器内存小于 8G 的话要留意一下。

4. 验证请求:容器日志与接口连通性检查

4.1 看容器日志确认启动成功

先看 agent 日志,这是最关键的一个:

docker logs -f hermes-agent

正常启动会看到 gateway 监听 8642 的输出,类似gateway listening on 0.0.0.0:8642。如果看到Permission denied或者HERMES_HOME相关报错,回到第 5 节排查。

再看 webui:

docker logs -f hermes-webui

webui 启动时会跑uv pip install,第一次启动会慢一些,日志里能看到依赖安装进度。装完之后会输出监听 8787 的信息。如果卡在安装阶段很久,检查hermes-agent-src卷是否被 agent 正确填充。

dashboard 日志:

docker logs -f hermes-dashboard

它连的是http://hermes-agent:8642,如果 agent 没起来,dashboard 会报连接失败,这是正常的依赖顺序问题,等 agent 起来后重启 dashboard 即可。

4.2 接口连通性验证

先在本机验证 agent 网关:

curl -s http://127.0.0.1:8642/health

返回 200 或健康状态 JSON 就说明网关活着。然后验证 webui:

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8787

返回 200 说明 webui 页面可访问。dashboard:

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9119

局域网访问的话,把127.0.0.1换成宿主机内网 IP,比如http://192.168.1.100:8787。如果本机能通、局域网不通,检查 CentOS 7 的 firewalld:

sudo firewall-cmd --add-port=8642/tcp --permanent sudo firewall-cmd --add-port=8787/tcp --permanent sudo firewall-cmd --add-port=9119/tcp --permanent sudo firewall-cmd --reload

最后验证模型调用链路是否真的通了。在 webui 里发一条消息,或者直接用 agent 的 CLI 触发一次请求。如果返回正常内容,说明 TaoToken 的 Key、Base URL、Model ID 三件套配置正确。如果报 401,说明 Key 有问题;如果报模型不存在,说明 Model ID 写错了。

5. 本篇常见报错排查:401、local proxy failed、reading choices、OAuth

5.1 401 Unauthorized

这是最常见的。日志里通常长这样:

error: 401 Unauthorized - invalid api key

原因基本是TAOTOKEN_API_KEY没传进容器,或者传了但值不对。先在宿主机确认.env里的值:

grep TAOTOKEN_API_KEY .env

然后进容器看环境变量有没有生效:

docker exec hermes-agent env | grep TAOTOKEN

如果容器里没有这个变量,说明 compose 里environment段没写对,或者.env文件不在 compose 执行目录下。注意.env必须和 compose 文件同目录,compose 才会自动加载。

5.2 local proxy failed

这个报错通常出现在 agent 尝试调用外部 API 时:

local proxy failed: dial tcp ... connection refused

先确认TAOTOKEN_BASE_URL是不是写成了带路径的形式。正确值是https://taotoken.net/api,不要写成https://taotoken.net/api/v1或者带查询参数。然后确认容器内能解析并访问这个域名:

docker exec hermes-agent curl -s -o /dev/null -w "%{http_code}\n" https://taotoken.net/api

如果容器内 DNS 解析失败,检查 CentOS 7 的/etc/resolv.conf,或者给 compose 的 network 加 DNS 配置。

5.3 reading choices 相关报错

日志里出现reading choices或者unexpected end of JSON input这类,一般是模型返回体解析失败。常见原因是 Model ID 填了一个不存在的模型,服务端返回了错误结构,agent 按正常响应去解析就崩了。解决办法是去模型对话页面确认可用的 Model ID,然后更新.env里的HERMES_MODEL,重启 agent:

docker compose -f docker-compose.three-container.yml up -d --force-recreate hermes-agent

5.4 OAuth 相关报错

如果日志里出现 OAuth 或者 token refresh 失败,说明 agent 在尝试走某种授权流程,但你用的是 API Key 模式,不应该触发 OAuth。检查是不是HERMES_HOME目录里残留了旧的凭证文件:

ls -la /data/hermes/home/

如果有credentials.json之类的文件,先备份再删掉,让 agent 重新按 API Key 模式初始化。另外确认 compose 里没有多余的 OAuth 相关环境变量。

5.5 权限类报错

如果日志是Permission denied且路径指向/home/hermes/.hermes,检查宿主机目录属主:

ls -ln /data/hermes/home

数字属主应该和.env里的 UID/GID 一致。不一致就改:

sudo chown -R 1000:1000 /data/hermes/home

SELinux 没关的话,别忘了前面那条chcon命令。

6. 后续怎么用:从验证到长期跑起来

三个容器都起来、接口都通之后,日常使用主要走 webui 的 8787 端口,浏览器打开就能聊天。dashboard 的 9119 用来观察会话和资源占用,agent 的 8642 是给程序化调用用的,比如你写脚本或者接其他工具时直接打这个网关。

如果你要长期跑 coding agent 或者定时任务,建议把 Coding Plan 的额度模型了解一下,和按量计费的 Key 是分开管理的:

https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

需要新建或轮换 Key 的时候去控制台:

https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite

接入细节和参数说明看文档:

https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

CentOS 7 这套环境跑起来之后,最需要注意的是别随便升级 Docker 到太新的版本,3.10 内核上容易出兼容问题。另外/data/hermes/home这个目录会随着会话和记忆增长,定期看一眼磁盘占用,别把根分区撑满。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询