Hermes Agent 能当你 24/7 在线的 AI 助手,但前提是它得一直活着。本地跑一下测试没问题,真要挂到 VPS 上持续运行,配置向导只是第一步——容器怎么编排、数据怎么持久化、崩溃了谁来拉起、密钥放哪里安全、Dashboard 怎么安全暴露,每个环节都有坑。
本文给你一套完整的 Docker 部署方案——从 $5/月 VPS 选型到 Docker Compose 配置,从 s6-overlay 进程监管到七层安全加固,从 Bitwarden 密钥管理到踩坑清单。所有配置都可以直接复制到你的服务器上运行,所有命令都经过验证。
适合谁:已经在本地跑通 Hermes Agent 的用户,现在想把它搬到 VPS 上 24/7 运行,需要一份不遗漏细节的生产部署指南。完全没用过 Hermes 的读者,建议先看 Hermes Agent 完全指南。
Docker 与 Hermes 的两种关系

开始之前需要分清一个容易混淆的概念:Hermes 与 Docker 有两种完全不同的交叉方式,官方文档开篇就做了区分,但很多人第一次看会搞混。
第一种:Agent 本体运行在容器内——这是本文的主线。把 Hermes 整个装进 Docker 容器,利用容器的隔离性和自动重启策略实现 24/7 持续运行。容器内包含完整的 Python 环境、Node.js 运行时、Playwright 浏览器自动化组件和 s6-overlay 进程管理器。你在消息平台(Telegram、Discord 等)发消息,容器里的 Hermes 收到并处理——容器就是 Agent 的家。
第二种:Docker 作为终端后端(Terminal Backend)——Agent 在宿主机运行,但把每条命令发到一个持久化 Docker 沙箱容器内执行。配置项是 terminal.backend: docker。这个沙箱容器跨工具调用、跨 /new 命令、跨子 Agent 持续存活,直到 Hermes 进程结束。这种方式的目的是安全隔离命令执行环境——Agent 要运行 rm -rf 之类的危险命令,破坏的是沙箱而不是宿主机。
两种方式可以叠加使用:Agent 本体运行在 Docker 容器 A 里,同时配置 terminal.backend: docker 让命令在另一个沙箱容器 B 里执行,实现双层隔离。本文聚焦第一种部署方式,第二种在终端后端对比章节简要覆盖。
Docker Compose 完整配置

最简可运行版本
一个 docker-compose.yml 解决全部问题:
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
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
三条命令启动:
mkdir -p ~/.hermes
docker run -it --rm -v ~/.hermes:/opt/data nousresearch/hermes-agent setup
docker compose up -d
第二条是交互式配置向导——输入 API Key、选择消息平台(Telegram/Discord/Slack/WhatsApp 等)、完成初始化。向导把密钥写入 ~/.hermes/.env,其他配置写入 ~/.hermes/config.yaml。建议在这一步就把消息平台配好,省得启动后再进容器改配置。
💡 通俗讲:setup 命令用完即销毁(--rm),它的唯一目的是往 ~/.hermes/ 写配置文件。写完之后 docker compose up -d 才是真正启动常驻容器。
生产级完整版(含健康检查与自动更新)
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: unless-stopped
command: gateway run
ports:
- "127.0.0.1:8642:8642"
volumes:
- hermes-data:/opt/data
environment:
- HERMES_DASHBOARD=1
- HERMES_UID=10000
- HERMES_GID=10000
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8642/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
deploy:
resources:
limits:
memory: 4G
cpus: "2.0"
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 3600 hermes
environment:
- WATCHTOWER_CLEANUP=true
volumes:
hermes-data:
关键设计决策逐条解释:
- 端口绑定
127.0.0.1:Gateway API 只监听本地回环地址,不暴露公网。外部访问由反向代理(Caddy 或 Nginx)统一处理 HTTPS 和认证。如果你只用 Telegram/Discord 消息平台而不需要 API 接口,端口映射可以直接去掉——消息平台走出站连接,不需要入站端口 - Named Volume:
hermes-data是 Docker 管理的命名卷,比 bind mount(直接映射宿主机目录)更安全。docker compose down不会删除命名卷,只有显式执行docker compose down -v才会清除——这在生产环境是关键的数据保护屏障 - Watchtower:每小时检查一次上游镜像是否有更新版本,有则自动拉取新镜像、停止旧容器、用新镜像重建容器,旧镜像自动清理。你不需要手动跑
docker compose pull——Watchtower 帮你做了 - healthcheck:每 30 秒探测一次 Gateway 的
/health端点。三次失败后标记为不健康,Docker 会重启容器。同时让depends_on其他服务时能等待 Gateway 真正就绪再启动
Gateway + Dashboard 分离部署
如果需要 Dashboard 以只读模式运行(更安全):
services:
gateway:
image: nousresearch/hermes-agent:latest
container_name: hermes-gateway
restart: unless-stopped
command: gateway run
ports:
- "127.0.0.1:8642:8642"
volumes:
- hermes-data:/opt/data
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8642/health"]
interval: 30s
timeout: 5s
retries: 3
deploy:
resources:
limits:
memory: 4G
dashboard:
image: nousresearch/hermes-agent:latest
container_name: hermes-dashboard
restart: unless-stopped
command: dashboard --host 127.0.0.1 --no-open
ports:
- "127.0.0.1:9119:9119"
volumes:
- hermes-data:/opt/data:ro
depends_on:
gateway:
condition: service_healthy
volumes:
hermes-data:
Dashboard 挂载数据卷为 :ro(只读),只能看不能改。
数据持久化:一个目录装所有状态
/opt/data(映射到宿主机 ~/.hermes/)是全部状态的唯一真值源:
| 路径 | 存什么 |
|---|---|
.env |
API Key 和密钥 |
config.yaml |
全部 Hermes 配置 |
SOUL.md |
Agent 人格/身份 |
sessions/ |
对话历史 |
memories/ |
持久化记忆 |
skills/ |
已安装技能 |
home/ |
子进程 HOME(git/ssh/gh/npm) |
cron/ |
定时任务定义 |
hooks/ |
事件钩子 |
logs/ |
运行日志 |
checkpoints/ |
项目快照(/rollback 用) |
关键限制:绝不可让两个 Gateway 容器同时写入同一数据目录——session 文件和 memory 存储不支持并发写入。如果你在一台机器上同时跑了两个 Hermes 容器指向同一个 ~/.hermes/,轻则对话历史丢失,重则配置文件损坏。需要多个 Agent 实例时,应该使用多 Profile 模式(后文详述)而非多容器共享数据。
备份方案
数据目录是全部状态的命脉,务必建立定期备份机制。Hermes 内置了备份和恢复命令,也可以用标准的 Docker Volume 快照方式:
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/backup/hermes"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# 方法 1:使用内置备份命令
docker exec hermes hermes backup
# 方法 2:Volume 快照(适合 cron 定期执行)
docker run --rm \
-v hermes-data:/source:ro \
-v "${BACKUP_DIR}:/backup" \
alpine tar czf "/backup/hermes-${TIMESTAMP}.tar.gz" -C /source .
恢复:
docker exec hermes hermes import /opt/data/backups/hermes-backup-YYYYMMDD.zip --force
VPS 选型与 24/7 部署
硬件需求
| 资源 | 最低 | 推荐 |
|---|---|---|
| CPU | 1 核 | 2 核 |
| 内存 | 1 GB(无浏览器) | 2-4 GB |
| 磁盘 | 500 MB | 2+ GB |
实际测试:不运行本地模型时 Hermes 使用不到 500 MB 内存,一个最便宜的 VPS 就能胜任。模型推理通过 API 调用(OpenRouter、Nous Portal、OpenAI 等),Agent 本身不做推理计算,轻度使用 API 费约 $2-5/月。浏览器自动化(Playwright/Chromium)是最吃内存的功能——如果你的 Agent 不需要打开网页、截图或填表单,1 GB 内存足够。需要浏览器功能时建议至少 2 GB,4 GB 更稳妥。
💡 通俗讲:Hermes 本身很轻量,像一个只负责调度的管家。真正干重活的是远端的大模型 API,管家只需要把指令传过去、把结果拿回来。所以便宜的 VPS 就够了。
VPS 提供商对比
| 提供商 | 起步价 | 亮点 |
|---|---|---|
| Hetzner | $4.49/月 | 欧洲数据中心、性价比最高 |
| Hostinger | $5/月 | 有 Hermes Agent 一键模板,最快部署 |
| DigitalOcean | $5/月 | Droplet 操作简单 |
| Vultr | $5/月 | 全球节点多 |
| Contabo | $5/月 | 详细社区教程 |
| Oracle Always Free | $0 | 4 OCPU / 24 GB ARM,免费 |
成本计算:$5/月 VPS + $2-5/月 API 费 = 每月 $7-10 拥有一个 24/7 在线的 AI Agent。Oracle Always Free 方案甚至可以把 VPS 成本降到零——4 OCPU / 24 GB ARM 的免费实例跑 Hermes 绰绰有余,只需要支付 API 调用费用。如果连 API 费用都想省,OpenRouter 的 :free 模型可以进一步降为零成本。
Hostinger 提供了专门的 Hermes Agent 应用目录(Application Catalog),选 VPS 计划后系统自动安装 Docker、部署容器,通过 SSH 运行 setup wizard 就能完成配置——全程不到 10 分钟。适合不想自己从头搭环境的用户。
从零到运行:完整步骤
# 1. SSH 连接 VPS(务必用 SSH,不要用提供商的浏览器终端)
ssh root@your-vps-ip
# 2. 安装 Docker
curl -fsSL https://get.docker.com | sh
systemctl enable docker
# 3. 创建数据目录
mkdir -p ~/.hermes
# 4. 运行配置向导
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setup
# 5. 启动网关(后台运行)
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
# 6. 验证
docker exec hermes hermes doctor
docker exec hermes hermes gateway status
避免使用 VPS 提供商的浏览器终端(如 Hetzner Cloud Console)。这些终端可能把
:渲染为;,把@错误替换——会静默破坏 Docker 的-v参数和 API Key。务必通过 SSH 连接。
6 种终端后端对比

Hermes 支持 6 种终端后端(Terminal Backend),决定了 Agent 执行命令的位置和隔离级别:
| 后端 | 执行位置 | 隔离级别 | 适用场景 | 成本 |
|---|---|---|---|---|
| local | 宿主机 | 无隔离 | 开发/可信环境 | $0 |
| docker | Docker 容器 | 容器隔离 | 生产网关沙箱 | $0 |
| ssh | 远程服务器 | 机器隔离 | 命令执行分离到独立机器 | VPS 费用 |
| singularity | Singularity 容器 | 容器隔离 | HPC/学术环境 | $0 |
| modal | Modal 云函数 | 云端沙箱 | 突发/GPU 工作负载 | 按秒计费 |
| daytona | Daytona 工作区 | 云端沙箱 | 持久化云开发环境 | 按需计费 |
Docker 终端后端配置
terminal:
backend: docker
docker_image: "nikolaik/python-nodejs:python3.11-nodejs20"
docker_forward_env: [] # 显式允许列表;空则容器无宿主机密钥
container_cpu: 1
container_memory: 5120 # MB
container_disk: 51200 # MB
container_persistent: true # 跨 Session 持久化文件系统
使用 Docker 终端后端时,危险命令检查被跳过——容器本身就是安全边界。
Modal 后端的成本数学
Modal 按秒计费,什么时候比 VPS 划算?
- 突发场景:每天 10 条命令 x 15 秒 x 2vCPU/4GB = 150 秒计算,每月几分钱。远低于 $5 VPS
- 稳定场景:每天持续 4 小时以上的计算,超过 VPS 成本
- 常驻网关:必须始终在线接收消息,Modal 不适用
经验法则:每天有效计算低于 2-3 小时用 Modal 更省;超过则 VPS 更划算。另外 Modal 每次函数调用有几秒冷启动惩罚——如果 Agent 连续发 ls、cat file.txt、grep foo 三条独立命令,就是三次冷启动。Hermes 的 Modal 后端可以在单次 Session 内保持容器温热来缓解这个问题,但编写批量脚本代替多条短命令仍然是更好的做法。
混合方案也是一种选择:网关在 $5 VPS 上常驻运行(接收消息、管理会话),重计算任务(GPU 推理、大规模数据处理)分发到 Modal。这样兼顾了常驻能力和弹性计算。
网关服务化:让 Hermes 永远在线
Docker 自动重启(最简方案)
如果你只用一个容器、不需要 Compose 的编排能力,--restart unless-stopped 一个参数就解决了崩溃恢复和系统重启后自动拉起的问题。只有手动执行 docker stop 才能停止——VPS 重启、Docker daemon 重启、Agent 进程崩溃,全都自动恢复:
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent gateway run
s6-overlay 进程监管(Docker 内部)
官方 Docker 镜像以 s6-overlay v3 作为 PID 1(替换了早期的 tini),提供容器内部的进程监管:
- Gateway 崩溃后几秒内自动重启,无需重建容器
- 多 Profile 模式下每个 Profile 的 Gateway 独立监管
- 日志自动旋转(每 Profile 10 份 x 1 MB)
gateway run 命令在 s6 容器内自动升级为监管语义:内部函数 _gateway_command_inner 检测到 s6 PID 1 后,将请求派发给 s6 service manager,然后执行 sleep infinity 保持 CMD 进程存活。递归保护通过 HERMES_S6_SUPERVISED_CHILD=1 环境变量实现,阻止监管子进程再次进入重定向。如果你需要调试启动过程,可以用 --no-supervise 标志或 HERMES_GATEWAY_NO_SUPERVISE=1 环境变量显式关闭监管模式。
💡 通俗讲:s6-overlay 就像容器里的保姆。Docker 的 --restart 只能在整个容器崩溃时重启——杀掉所有进程再全部重来。s6 更精细,Gateway 进程崩了几秒内就拉起来,其他进程(如 Dashboard)完全不受影响。
systemd(Linux 原生安装)
如果选择不用 Docker 而是直接安装 Hermes:
[Unit]
Description=Hermes Agent Gateway
After=network.target
[Service]
Type=simple
User=hermes
WorkingDirectory=/home/hermes
ExecStart=/home/hermes/.local/bin/hermes gateway
Restart=always
RestartSec=10
Environment=PATH=/home/hermes/.local/bin:/usr/bin:/bin
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable hermes-gateway
sudo systemctl start hermes-gateway
launchd(macOS)
hermes gateway install 自动注册 launchd plist。但有一个陷阱:每次 gateway install 会从内置模板重新生成 plist,默认 WorkingDirectory 指向 pipx 包目录。需要手工修补:
plutil -replace WorkingDirectory \
-string '/your/working/directory' \
~/Library/LaunchAgents/ai.hermes.gateway.plist
hermes gateway restart
pipx upgrade hermes-agent 后如果重新安装了 gateway service,同样需要重做修补。
四种方式对比
| 方式 | 优势 | 劣势 |
|---|---|---|
Docker --restart |
隔离好、升级简单、跨平台 | 多一层抽象 |
| s6-overlay(Docker 内) | 多 Profile 监管、秒级崩溃恢复 | 需理解 s6 日志机制 |
| systemd | 系统级集成、journald 日志 | 仅 Linux;依赖自己管 |
| launchd | macOS 原生 | plist 被 gateway install 覆盖 |
反向代理与 Dashboard 安全
Dashboard 认证机制
官方支持三种 Dashboard 认证模式:
| 模式 | 配置 | 适用场景 |
|---|---|---|
| 用户名/密码 | HERMES_DASHBOARD_BASIC_AUTH_USERNAME + PASSWORD |
自建/VPN 后面 |
| OAuth(Nous Portal) | HERMES_DASHBOARD_OAUTH_CLIENT_ID |
公开部署 |
| 自建 OIDC | HERMES_DASHBOARD_OIDC_ISSUER + CLIENT_ID |
企业身份提供者 |
安全设计:无认证且绑定非回环地址时,Dashboard 启动直接报错拒绝(fail closed)。HERMES_DASHBOARD_INSECURE=1 可绕过但会暴露 API Key。
SSH 隧道(最简安全方案)
ssh -L 9119:localhost:9119 user@vps-ip
# 本地浏览器打开 http://localhost:9119
Caddy 反向代理(自动 HTTPS)
hermes.yourdomain.com {
reverse_proxy localhost:8642
basicauth /* {
admin $2a$14$... # caddy hash-password 生成
}
}
dashboard.yourdomain.com {
reverse_proxy localhost:9119
basicauth /* {
admin $2a$14$...
}
}
Caddy 自动申请和续期 Let's Encrypt 证书,零配置 HTTPS。
Nginx 反向代理(含 WebSocket 支持)
server {
listen 443 ssl;
server_name hermes.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/hermes.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hermes.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8642;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s; # SSE 长连接
}
}
proxy_read_timeout 3600s 是关键——Hermes 的 SSE(Server-Sent Events)长连接需要足够长的超时时间。
安全加固:七层纵深防御

AI Agent 有自主执行命令的能力,这意味着安全性比普通 Web 应用更关键。如果模型被提示注入(prompt injection)攻击——比如用户在文件里藏了一条"删除所有数据"的指令——Agent 可能真的去执行。Hermes 对此建立了七层纵深防御模型(Defense in Depth),每一层都是一道独立的安全屏障:
- 用户授权——允许列表控制谁能与 Agent 对话,生产环境禁用
GATEWAY_ALLOW_ALL_USERS=true - 危险命令审批——人在回路审批破坏性操作。三种模式:
manual(始终提示审批)、smart(辅助模型评估风险)、off(等同--yolo) - 容器隔离——Docker 沙箱 + 加固参数,即使 Agent 执行恶意命令也限制在容器内
- MCP 凭据过滤——MCP 子进程的环境变量被隔离,Agent 无法通过 MCP 工具泄露宿主机密钥
- 上下文文件扫描——项目文件在加载前检测提示注入模式
- 跨 Session 隔离——Session 无法访问彼此数据;Cron 存储路径防路径穿越
- 输入消毒——终端工具后端的工作目录参数基于允许列表验证
此外还有一个硬编码黑名单(Always-On Floor)——即使在 --yolo 模式、approvals.mode: off 下也绝对不执行的命令:rm -rf / 及变体、Bash fork bomb、mkfs.* 对已挂载设备、dd if=/dev/zero of=/dev/sd*、将不受信 URL 管道到 sh。
Docker 安全参数详解
容器启动时自动附加的安全参数:
--cap-drop ALL # 丢弃全部 Linux capabilities
--cap-add DAC_OVERRIDE # root 可写绑定挂载目录
--cap-add CHOWN # 包管理器需要
--cap-add FOWNER # 包管理器需要
--security-opt no-new-privileges # 阻止特权提升
--pids-limit 256 # 限制进程数(防 fork bomb)
--tmpfs /tmp:rw,nosuid,size=512m # 有限大小的 /tmp
--tmpfs /var/tmp:rw,noexec,nosuid,size=256m # 不可执行的 /var/tmp
容器内用户降权
官方镜像通过 s6-setuidgid hermes(UID 10000)降权运行——不再以 root 身份执行 Agent 逻辑。这解决了早期 GitHub Issue #3969 中社区报告的三个安全关注:容器以 root 运行、有过多 capabilities、建议加固为非 root 运行。
官方在 s6-overlay 迁移 PR #30136(+6794/-215,40 个文件)中彻底解决了这些问题——移除了 gosu,改用 s6-setuidgid 降权,同时加入了 hadolint 和 shellcheck 构建输入检查。
Rootless Docker 部署
AI Agent 沙箱的推荐选择。安装:
dockerd-rootless-setuptool.sh install
额外加固措施:
--read-only # 根文件系统只读
--tmpfs /tmp:size=512m # 显式可写临时目录
网关/沙箱分离架构
企业级方案(来自 Simon Gajdosik 的实践):
- 两台 VPS 通过 Tailscale 连接:一台持有 OAuth token 与消息平台通信,一台运行 Shell 命令
- Agent 永远不 SSH 到普通 Linux Shell——它 SSH 到 rootless 容器内的
/workspace - 如果模型被提示注入,最坏情况是在无特权容器中探索——该机器没有生产密钥、没有公网 SSH 端口
网络隔离最佳实践
- Gateway API 端口仅绑定
127.0.0.1 - Dashboard 仅通过 SSH 隧道暴露
- 消息平台走出站连接(Telegram/Discord 长轮询),无需开放入站端口
- SSRF 防护:所有 URL 工具(Web 搜索、提取、浏览器)在获取前验证 URL,阻止 SSRF 攻击。黑名单包括 RFC 1918 私网(
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)、回环(127.0.0.0/8)、链路本地(169.254.0.0/16,含云元数据169.254.169.254)、CGNAT 地址空间(100.64.0.0/10,覆盖 Tailscale/WireGuard VPN) - Tirith 预执行扫描:集成 tirith 做命令级安全扫描——检测同形字 URL 欺骗、管道到解释器模式、终端注入攻击。首次使用时自动下载并 SHA-256 校验
凭据文件权限
chmod 600 ~/.hermes/.env # 仅所有者可读写
生产部署检查清单(官方 10 条)
- 设置显式允许列表——生产环境禁用
GATEWAY_ALLOW_ALL_USERS=true - 使用容器后端——
terminal.backend: docker - 限制资源——CPU、内存、磁盘
- 安全存储密钥——
.env文件权限 600 - 启用 DM 配对——用配对码代替硬编码用户 ID
- 审查命令允许列表——定期审计
command_allowlist - 设置
terminal.cwd——不让 Agent 在敏感目录操作 - 以非 root 运行——不以 root 运行网关
- 监控日志——检查未授权访问
- 保持更新——定期
docker compose pull
密钥管理:Bitwarden Secrets Manager

生产环境把 API Key 明文写在 .env 里不理想。Hermes 原生集成了 Bitwarden Secrets Manager(BSM):
工作原理
- 在 BSM 创建 machine account,授予项目读权限,生成 access token
- Hermes 将 token 存入
~/.hermes/.env的BWS_ACCESS_TOKEN - 每次启动时调用
bws secret list,将返回的 Key 设入环境变量 - 默认覆盖已有环境变量——Bitwarden 是唯一真值源
在 Bitwarden Web 端轮换一次 Key,所有 Hermes 进程下次启动即生效——不需要逐台机器改 .env 文件。bws 二进制在首次使用时自动下载到 ~/.hermes/bin/,版本固定为 v2.0.0(不自动升级到 latest,确保可复现性),无需 apt/brew/sudo。
这在多机器部署场景下特别有价值。假设你有三台 VPS 各跑一个 Hermes 实例,传统做法是 SSH 到每台机器修改 .env 里的 API Key;用 Bitwarden 后,只在 Web 端改一次,三台机器下次重启时自动拉取新密钥。
配置
hermes secrets bitwarden setup
向导自动完成:下载并校验 bws v2.0.0 -> 提示输入 access token -> 选择区域 -> 列出项目 -> 测试拉取 -> 启用。
对应的 config.yaml 配置项:
secrets:
bitwarden:
enabled: true
access_token_env: BWS_ACCESS_TOKEN
project_id: "your-project-id"
server_url: "" # 空=US Cloud;EU 设 https://vault.bitwarden.eu
cache_ttl_seconds: 300
override_existing: true
auto_install: true
容错设计
Bitwarden 永不阻塞 Hermes 启动——任何失败仅输出一行警告,Hermes 继续使用 .env 中已有的凭据。
适用场景判断
| 场景 | 推荐方案 |
|---|---|
| 单机个人部署 | .env 足够 |
| 多机器集群 / 团队共享 | Bitwarden Secrets Manager |
| 气隙环境 | .env(无法访问 Bitwarden API) |
| 已有 CI/CD 密钥注入 | 用现有机制 |
多 Profile 部署:一容器多 Agent

s6 迁移后,推荐"一个容器多个 Profile"模式:
# 创建 Profile
docker exec hermes hermes profile create work
docker exec hermes hermes profile create personal
# 查看监管状态
docker exec hermes s6-rc -a list
# 查看特定 Profile 日志
docker exec hermes tail -f /opt/data/logs/gateways/work/current
# 停止/启动特定 Profile
docker exec hermes hermes gateway stop --profile work
docker exec hermes hermes gateway start --profile work
一容器多 Profile vs 一 Profile 一容器
| 维度 | 一容器多 Profile | 一 Profile 一容器 |
|---|---|---|
| 磁盘开销 | 一份镜像、一个 venv | N 份 |
| 内存开销 | 共享 Python 解释器缓存 | 每容器重复 |
| Profile 创建 | docker exec 秒级完成 |
新 docker run + 端口分配 |
| 崩溃恢复 | s6-supervise 自动重启 | Docker --restart(更慢) |
| 备份 | 一个 ~/.hermes 目录 |
N 个目录 |
仍需独立容器的场景:资源隔离需求(--memory/--cpus 每 Profile 不同)、独立镜像版本、网络分段、合规/爆炸半径控制。
每个 Profile 可以连接不同的 Telegram/Discord 频道、使用不同的模型、有独立的 SOUL.md 人格定义。例如创建一个 work Profile 连接公司 Slack,一个 personal Profile 连接个人 Telegram——两个 Agent 共享一个容器但彼此完全隔离。
官方还支持 Profile Distributions(配置文件分发)——将完整 Agent 打包为可分发单元,部署到多台机器或跨机器同步状态。适合团队部署和边缘节点同步。
升级与维护流程

Docker Compose 升级(推荐)
docker compose pull # 拉取新镜像
docker compose up -d # 基于新镜像重建容器
数据卷保留,容器启动时自动运行非交互式 config-schema 迁移——如果新版本修改了配置文件格式,迁移脚本会自动转换。Watchtower 可自动化整个流程,你甚至不需要手动执行这两条命令。
升级前的最佳实践:先备份数据目录,再升级。虽然官方保证向后兼容,但多一层保险总没坏处。
单容器升级
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 exec hermes hermes doctor # 全面自检
docker exec hermes hermes gateway status # 网关状态
docker exec hermes hermes status # 模型/provider 状态
docker logs -f hermes --tail 50 # 最近日志
日志路由
s6 容器有四个日志面:
| 来源 | 落地位置 | 读取方式 |
|---|---|---|
| 每 Profile Gateway | ~/.hermes/logs/gateways/<profile>/current |
tail -F |
| Dashboard | docker logs |
docker logs -f hermes |
| Boot reconciler | ~/.hermes/logs/container-boot.log |
tail -F |
| 通用 Hermes 日志 | ~/.hermes/logs/agent.log |
docker exec hermes hermes logs --follow |
连接本地推理服务器
如果想用本地模型(vLLM、Ollama 等)配合 Docker 部署的 Hermes:
Docker Compose 方式(推荐)
把 Hermes 和推理服务器放在同一 Docker 网络:
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:
- "127.0.0.1:8642:8642"
volumes:
- ~/.hermes:/opt/data
networks:
- hermes-net
networks:
hermes-net:
driver: bridge
config.yaml 使用容器名作为主机名:
model:
provider: custom
model: my-model
base_url: http://vllm:8000/v1
api_key: "none"
宿主机推理服务器
- macOS/Windows:使用
host.docker.internal访问宿主机服务 - Linux:使用
--network host或host.docker.internal(Docker 20.10+)
Ollama
如果用 Ollama 作为推理后端,同样放在 Docker 网络内:
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
volumes:
- ollama-data:/root/.ollama
networks:
- hermes-net
config.yaml 配置:base_url: http://ollama:11434/v1
更多本地模型部署细节参考 Hermes Agent 本地模型指南。
云平台托管方案
除了自建 VPS,还有多种云平台提供一键部署:
| 平台 | 方式 | 特点 | 适用场景 |
|---|---|---|---|
| Hostinger | 应用目录一键 | 最快路径,Docker Manager 可视化 | 不想碰命令行 |
| Fly.io | 官方蓝图 fly deploy |
持久卷,无需 Dockerfile | 已有 Fly 账号 |
| Render | One-click Blueprint | 持久磁盘 + Dashboard | 一键部署 |
| Coolify | 开源 PaaS 模板 | 自动 HTTPS、Git 集成、$5 VPS 搭配 | 自建 Heroku 替代 |
| Oracle Free | Terraform | 4 OCPU/24GB ARM/$0 | 零成本方案 |
| AWS Marketplace | 预构建 AMI | 预配 Docker+Tailscale+Caddy | 企业合规 |
Coolify 一键部署

Coolify 是 57K Stars 的开源自托管 PaaS,已合并 Hermes Agent 模板:
# 安装 Coolify
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
# 在 Web UI 搜索 Hermes Agent → Deploy
模板自动创建双容器栈:WebUI 公开(自动生成域名和密码、自动 HTTPS via Let's Encrypt)、Agent Gateway 内部运行不暴露公网。共享 Named Volume 存储配置、会话和记忆,默认使用嵌入式 SQLite。把 Coolify 装在 $5/月的 Hetzner VPS 上,成本远低于 Vercel Pro,同时获得 280+ 一键模板、Git 集成(推送部署)和多服务器管理能力。
hermes-anywhere:Terraform 多云
开源 Terraform 方案,一条命令部署到 5 个云:
terraform apply # 选择 Oracle/Hetzner/GCP/AWS/DigitalOcean
make doctor # 健康检查
make backup # GPG 加密备份
踩坑清单
基于官方文档、社区实践和实际部署经验总结:
| 坑 | 现象 | 解决 |
|---|---|---|
| 浏览器终端破坏字符 | API Key 中的 : 变 ;、@ 被替换 |
务必用 SSH 连接,不用 VPS 浏览器终端 |
| UID/GID 不匹配 | 容器内文件权限报错 | 设置 HERMES_UID=$(id -u) HERMES_GID=$(id -g) |
| 两个 Gateway 写同一数据目录 | session 损坏、记忆丢失 | 一个数据目录只允许一个 Gateway 进程 |
| Dashboard 绑公网无认证 | 启动直接报错 | 加 BasicAuth / OAuth / SSH 隧道 |
| Docker socket 暴露 | 容器逃逸风险 | 仅在需要 Docker 终端后端时挂载 socket |
| Watchtower 自动更新失败 | 镜像标签问题(manifest unknown) | 确认镜像标签为 latest 或指定具体 tag |
| Named Volume 误删 | docker compose down -v 清除数据 |
生产环境永远不带 -v;定期备份 |
| SELinux 标签问题 | 挂载文件访问被拒 | 卷挂载加 :Z 后缀 |
| 内存不足 OOM | 浏览器自动化触发 OOM | 加 deploy.resources.limits.memory: 4G 或关闭浏览器工具 |
| s6 日志不旋转 | 磁盘被日志撑满 | 检查 /opt/data/logs/gateways/ 旋转配置 |
FAQ
Hermes Agent Docker 镜像包含什么?
基于 debian:13.4,包含:Python 3 全依赖、Node.js + npm(WhatsApp 桥接)、Playwright + Chromium(浏览器自动化)、ripgrep、ffmpeg、git、docker-cli(可驱动宿主机 Docker)、openssh-client、s6-overlay v3 作为 PID 1。压缩约 2.6 GB。
消息平台需要开放入站端口吗?
不需要。Telegram、Discord 等消息平台使用出站长轮询连接——Agent 主动连平台,不需要平台连进来。端口映射 8642 只在需要外部调用 Gateway API 时才需要。
如何查看 Hermes 使用了多少资源?
docker stats hermes # 实时 CPU/内存/网络
docker exec hermes hermes doctor # 内部自检
能用 Podman 代替 Docker 吗?
可以。官方 NixOS 模块支持 Podman 替代。社区也有 Rootless Podman 部署的讨论。命令基本兼容,把 docker 替换为 podman 即可。
检查点(Checkpoint)在 Docker 里怎么用?
检查点数据存储在 /opt/data/checkpoints/ 目录下,通过数据卷持久化。容器重建后检查点历史保留。管理命令:
docker exec hermes hermes checkpoints status
docker exec hermes hermes checkpoints prune --retention-days 7 --max-size-mb 500
支持哪些 NAS 部署?
QNAP(官方教程覆盖 Container Station)和 Synology(Container Manager)都支持。关键注意 UID/GID 映射:
docker run -d --name hermes \
-e PUID=1000 -e PGID=10 \
-v /volume1/docker/hermes:/opt/data \
nousresearch/hermes-agent gateway run
如何实现零成本部署?
Oracle Cloud Always Free Tier:4 OCPU / 24 GB ARM / $0。配合 hermes-anywhere Terraform 方案一键部署。API 费用使用 OpenRouter :free 模型可进一步降为零。
从 tini 迁移到 s6-overlay 需要改配置吗?
不需要。官方已在镜像层面完成迁移(PR #30136),用户无需改 docker-compose.yml 或命令。升级到最新镜像即自动使用 s6-overlay。
下一步
- 回到 Pillar:Hermes Agent 完全指南
- 降低运行成本:Hermes Agent 成本控制实战
- 使用本地模型:Hermes Agent 本地模型指南
- 实测体验:我替翔宇测了 Hermes Agent


























