Skip to main content

在 VPS 上安装 Hermes Agent(AI 智能体)

本指南介绍如何在 HostMyServers VPS 上安装 Hermes Agent。Hermes 是由 Nous Research 开发的开源 AI 智能体框架(MIT 许可证)。与您在本地电脑上实时使用的编程助手(Claude Code、OpenCode…)不同,Hermes 在服务器上持续运行:您通过即时通讯工具(Discord、Telegram、Slack…)与它对话,它在后台自主工作,记住您的对话内容,学习新的流程(skills),并可执行定时任务。

部署基于 Docker Compose 和加固配置,Web 管理界面仅能通过 VPN(Tailscale)访问,绝不暴露在互联网上。

来源

本指南参考了文章 《Hermes : simple hype ou vraie révolution ?》(《Hermes:只是炒作还是真正的革命?》,damyr.fr)中的实践经验以及 Hermes Agent 官方文档

订购服务器

Hermes 不在本地运行 AI 模型:它调用远程模型(OpenRouter、Anthropic、Nous Portal…)。因此一台小型 VPS 就绰绰有余:

前提条件

  • root SSH 访问权限或具有 sudo 权限的用户
  • Ubuntu 24.04 LTSDebian 12/13 系统
  • 一个模型提供商账户(例如 OpenRouter)及 API 密钥
  • 一个 Tailscale 账户(个人使用免费),用于访问 Web 界面
  • 一个 Discord 账户(或 Telegram、Slack…),用于与智能体对话

配置要求

组件最低配置推荐配置
内存2 GB4 GB
CPU1 vCPU2 vCPU
存储10 GB20 GB
内存

文章作者在 2 vCPU / 2 GB 的 VPS 上运行 Hermes,但建议一旦使用浏览器自动化(Playwright/Chromium)或多个子智能体,至少配备 4 GB 内存

请通过 SSH 连接,而不是 Web 控制台

浏览器控制台(noVNC)对某些字符(:@=)传输不佳,可能会悄无声息地破坏粘贴的命令和 API 密钥。请使用真正的 SSH 会话。

连接并更新系统

ssh user@server_ip
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg openssl

安装 Docker

官方 Docker 镜像是 Hermes 推荐的安装方式:镜像无状态,所有数据都保存在一个挂载目录(/opt/data)中,更新只需拉取新镜像即可。

从 Docker 官方仓库安装 Docker Engine 和 Compose 插件:

sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release
curl -fsSL https://download.docker.com/linux/$ID/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$ID $VERSION_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

验证安装:

docker --version
docker compose version

安装 Tailscale(私有访问)

Hermes 的 Web 界面可以管理一切(API 密钥、配置、MCP、插件、通过智能体执行命令)。它绝不能暴露在互联网上:监听在 0.0.0.0 上的实例曾被自动扫描器攻破(通过智能体植入恶意 SSH 密钥)。因此我们只允许从您的 Tailscale 私有网络访问它。

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

打开显示的认证链接,将服务器绑定到您的 Tailscale 账户,然后获取 VPS 的 Tailscale IP 地址(100.x.y.z 网段):

tailscale ip -4

记下这个地址:它将作为 Web 界面的监听地址。同时在您的电脑或手机上安装 Tailscale,以便访问该界面。

为什么要将端口绑定到 Tailscale IP?

Docker 会写入自己的 iptables 规则,对已发布的端口会绕过 UFW 防火墙。将端口发布在 Tailscale 地址上(而不是 0.0.0.0)可以确保无论防火墙状态如何,都无法从公网接口访问该端口。

准备目录

sudo mkdir -p /opt/hermes/data
sudo chown -R 10000:10000 /opt/hermes/data
sudo chmod 0750 /opt/hermes/data
cd /opt/hermes

容器以非特权用户 UID/GID 10000 运行智能体:数据目录必须归该用户所有。

环境变量文件

创建 /opt/hermes/.env 文件,用于保存 Web 界面的监听地址和登录凭据:

sudo nano /opt/hermes/.env
# 服务器的 Tailscale 地址(`tailscale ip -4` 的输出)— 绝不能是 0.0.0.0
HERMES_BIND_ADDR=100.x.y.z
HERMES_DASHBOARD_PORT=9119

# Web 界面登录凭据
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=PASSWORD
HERMES_DASHBOARD_BASIC_AUTH_SECRET=SECRET

# 资源限制(根据您的 VPS 调整:2 GB 约 1200m,4 GB 为 3g)
HERMES_MEMORY_LIMIT=1200m
HERMES_CPU_LIMIT=1.5

TZ=Europe/Paris

生成密码和会话密钥,然后填入文件:

openssl rand -base64 24 # -> HERMES_DASHBOARD_BASIC_AUTH_PASSWORD
openssl rand -hex 32 # -> HERMES_DASHBOARD_BASIC_AUTH_SECRET
密钥至少 16 字节

HERMES_DASHBOARD_BASIC_AUTH_SECRET 必须至少 16 字节。否则认证模块不会启用,界面会拒绝启动,并给出误导性的错误 “no auth providers are registered”openssl rand -hex 32 完全足够。请保持此密钥不变:更改它会使已打开的会话失效。

保护该文件,它包含敏感信息:

sudo chmod 0600 /opt/hermes/.env

Docker Compose 配置

创建 /opt/hermes/compose.yaml

sudo nano /opt/hermes/compose.yaml
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
command: gateway run
restart: unless-stopped
stop_grace_period: 30s

# 容器内任何进程都无法获取新权限
security_opt:
- no-new-privileges:true
# 移除所有默认的 Linux capabilities……
cap_drop:
- ALL
# ……只保留容器初始化所需的那些
cap_add:
- CHOWN
- FOWNER
- DAC_OVERRIDE
- SETUID
- SETGID
- KILL
# 避免因打开文件过多而出错
ulimits:
nofile:
soft: 4096
hard: 8192

ports:
# Web 界面仅发布在 Tailscale 地址上
- "${HERMES_BIND_ADDR}:${HERMES_DASHBOARD_PORT:-9119}:${HERMES_DASHBOARD_PORT:-9119}"

volumes:
# 智能体的全部数据:配置、密钥、记忆、skills、定时任务、日志
- ./data:/opt/data
# 绝不要挂载 /var/run/docker.sock:这相当于授予宿主机 root 权限

environment:
PUID: "10000"
PGID: "10000"
TZ: "${TZ:-Europe/Paris}"
# Web 界面(与 gateway 在同一容器中受监管运行)
HERMES_DASHBOARD: "1"
HERMES_DASHBOARD_HOST: "0.0.0.0" # 仅限容器内部;宿主机上只暴露 Tailscale
HERMES_DASHBOARD_PORT: "${HERMES_DASHBOARD_PORT:-9119}"
HERMES_DASHBOARD_BASIC_AUTH_USERNAME: "${HERMES_DASHBOARD_BASIC_AUTH_USERNAME}"
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD: "${HERMES_DASHBOARD_BASIC_AUTH_PASSWORD}"
HERMES_DASHBOARD_BASIC_AUTH_SECRET: "${HERMES_DASHBOARD_BASIC_AUTH_SECRET}"
# 智能体安全防护
HERMES_WRITE_SAFE_ROOT: "/opt/data" # 智能体只能写入其数据目录
HERMES_YOLO_MODE: "0" # 危险命令仍需审批

shm_size: "256m"

deploy:
resources:
limits:
memory: "${HERMES_MEMORY_LIMIT:-1200m}"
cpus: "${HERMES_CPU_LIMIT:-1.5}"
pids: 512

# 防止输出过多的智能体占满磁盘
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
社区加固镜像

文章作者发布了官方镜像的一个变体(DamyrFr/hermes-docker),主要增加了 rtk(过滤命令输出以减少 token 消耗)并移除了 setuid 二进制文件。上述配置在官方镜像的基础上沿用了其安全设置。

首次启动:配置向导

在启动服务之前,先运行一次交互式向导(文本界面)。它会询问您的模型提供商、API 密钥,并引导您配置即时通讯(gateway):

cd /opt/hermes
sudo docker compose run --rm hermes setup

在向导中:

  1. 模型提供商:例如选择 OpenRouter 并粘贴您的 API 密钥。替代方案:使用 Nous Portal 订阅运行 hermes setup --portal(包含 300 多个模型和 Web 工具,无需管理密钥)。
  2. 工具:启用网页搜索和网页内容提取(见下文)。
  3. 即时通讯:配置 Discord(见下一节)— 这是与智能体交互的主要界面。
  4. 不太明白的参数可以保持默认,之后都可以修改。

密钥保存在 /opt/hermes/data/.env,配置保存在 /opt/hermes/data/config.yaml

使用 OpenRouter 控制预算

OpenRouter 允许为每个 API 密钥设置支出上限,并可定期重置。非常适合按用量计费的个人实例。

创建 Discord 机器人(gateway)

Gateway 是将 Hermes 连接到您的即时通讯工具的组件。Discord 是最常用的选项之一:频道和话题串可以很好地组织对话。

  1. 前往 Discord Developer Portal,点击 New Application
  2. Bot 选项卡中,启用以下 Privileged Gateway Intents,然后点击 Save Changes
    • Message Content Intent(必需:否则机器人收到的消息为空)
    • Server Members Intent(必需)
  3. 仍在 Bot 中,点击 Reset Token 并复制令牌。
  4. 通过 Installation 选项卡(或 OAuth2 → URL Generator,scope 选 bot)将机器人邀请到您的 Discord 服务器。
  5. 获取您的 Discord 用户 ID:启用开发者模式(设置 → 高级),然后右键点击您的用户名 → 复制用户 ID

如果您没有在向导中完成此步骤,请运行 gateway 配置:

sudo docker compose run --rm hermes gateway setup

或者直接将以下内容添加到 /opt/hermes/data/.env

DISCORD_BOT_TOKEN=your-bot-token
DISCORD_ALLOWED_USERS=123456789012345678
限制机器人的访问

DISCORD_ALLOWED_USERS(或 DISCORD_ALLOWED_ROLES)列出唯一允许向智能体下达指令的人员。未设置此变量时,出于安全考虑 Hermes 会拒绝所有人。只添加可信任的人:智能体可以在服务器上执行命令。

默认情况下,Hermes 会回复您的所有私信,而在频道中只有被 @提及 时才会回复。

启动服务

cd /opt/hermes
sudo docker compose up -d
sudo docker compose logs -f --tail=100

restart: unless-stopped 会在崩溃或 VPS 重启后自动重新启动容器(即使开机时 Tailscale 接口尚未就绪:Docker 会不断重试,直到接口可用)。

确认端口仅发布在 Tailscale 地址上:

sudo ss -tlnp | grep 9119

输出应显示 100.x.y.z:9119,而不是 0.0.0.0:9119

然后在 Discord 上给您的机器人发送一条私信:它应该会回复您。

访问 Web 界面

在已连接到您 Tailscale 网络的设备上打开:

http://100.x.y.z:9119

使用 /opt/hermes/.env 中定义的凭据登录。界面可用于与智能体对话、查看日志、管理配置、MCP、配置文件和插件,还提供一个 Kanban 看板:您创建一个任务,智能体将其拆分为子任务分配给子智能体,卡片会自动推进。

数据目录结构

智能体的全部状态都位于 /opt/hermes/data(在容器中挂载为 /opt/data):

路径作用
config.yaml全局参数:模型、工具、审批、委派
.envAPI 密钥(模型提供商、Discord、Web 工具…)
auth.json认证信息(OAuth、即时通讯平台)
SOUL.md智能体的个性(名字、语气、交互方式)
skills/智能体学习并随时间不断改进的流程
cron/定时任务
state.db智能体的记忆:会话、历史记录…(切勿在运行时修改或复制

自定义智能体

赋予它个性(SOUL.md)

SOUL.md 文件定义了智能体的性格和表达方式。给它起个名字并设定语气:这会让日常交流更加愉快。

sudo nano /opt/hermes/data/SOUL.md
# Janet

你是 Janet,一位乐于助人、简洁且略带俏皮的助手。
你用中文回答,直奔主题,并在执行任何不可逆操作之前
请求确认。

选择模型

一个不错的折中方案是:对话使用快速且廉价的模型,而子智能体的自主工作(委派)使用更强大的模型。以下是在 /opt/hermes/data/config.yaml 中使用 OpenRouter 的配置示例:

model:
default: deepseek/deepseek-v4.1-flash
provider: openrouter
base_url: https://openrouter.ai/api/v1
api_mode: chat_completions

delegation:
max_iterations: 50
model: z-ai/glm5.3
provider: openrouter
note

这些模型是文章撰写时给出的示例。模型格局变化很快:请根据您的预算和需求进行选择。您也可以在 Discord 中使用 /model 命令切换模型。

用于代码审查的第二个智能体

为避免模型审查自己的工作,可以创建一个使用其他模型(例如 Claude Opus)的独立配置文件,然后要求主智能体在将代码提交给您之前,始终先让它审查:

sudo docker compose run --rm hermes profile create reviewer

之后可在 Web 界面的 Profiles(配置文件) 栏目中配置该配置文件(模型、提供商)。

网页搜索

为了自主搜索互联网,智能体使用两个工具:

  • web_search:查找相关链接。duckduckgo-search 可在本地免费运行。
  • web_extract:将一个或多个网页转换为 Markdown。Tavily 提供带免费额度的密钥。

可在 Web 界面中或通过 sudo docker compose run --rm hermes tools 启用它们。

定时任务(cron)

Hermes 原生支持定时任务。最简单的方法是直接在 Discord 中提出请求:

/cron add "every 2h" "检查服务器状态,如有异常请通知我"
/cron add "every 1d" "帮我收集 DevOps 新闻并总结最重要的 5 条"

使用思路:多来源自动信息监测、定期导入 Obsidian 知识库(“第二大脑”)、定期报告。默认情况下,由定时任务触发的危险命令会被拒绝approvals.cron_mode: deny)。

安全:最佳实践

  • Web 界面:仅通过 Tailscale(或其他 VPN)访问,绝不监听在 0.0.0.0 上,始终启用认证。
  • 审批:保持 approvals.mode: smart(默认),或在 config.yaml 中改为 manual。对于连接到即时通讯工具的智能体,切勿使用 --yolo / approvals.mode: off
  • 即时通讯访问:将 DISCORD_ALLOWED_USERS 限制为仅您本人。
  • Docker 套接字:切勿将其挂载到容器中。
  • API 密钥:使用设有支出上限的专用密钥,并谨慎对待授予集成(GitHub、电子邮件、MCP…)的权限。
  • 防火墙:公网接口上只开放 SSH。参见 保护您的 Linux 服务器

常用命令

操作命令(在 /opt/hermes 目录下)
查看日志sudo docker compose logs -f --tail=100
重启sudo docker compose restart
停止sudo docker compose down
重新运行向导sudo docker compose run --rm hermes setup
切换模型sudo docker compose run --rm hermes model
诊断sudo docker compose run --rm hermes doctor
tip

在使用 docker compose run 修改配置之前,请先停止服务(docker compose down),然后使用 docker compose up -d 重新启动。

更新

由于镜像是无状态的,只需拉取新版本并重新创建容器:

cd /opt/hermes
sudo docker compose pull
sudo docker compose up -d

备份

整个智能体(配置、密钥、记忆、skills、定时任务)都位于 /opt/hermes/datastate.db 数据库不能在智能体运行时复制:请在归档期间停止它。

cd /opt/hermes
sudo docker compose stop
sudo tar czf /root/hermes-backup-$(date +%F).tar.gz -C /opt/hermes data .env compose.yaml
sudo docker compose start

请将这些归档保存在服务器之外:它们包含您的 API 密钥。

故障排除

Web 界面无法启动(“no auth providers are registered”)

  • 确认 HERMES_DASHBOARD_BASIC_AUTH_SECRET 至少为 16 字节(使用 openssl rand -hex 32)。
  • 确认 /opt/hermes/.env 中三个 HERMES_DASHBOARD_BASIC_AUTH_* 变量均已正确填写。

容器无法启动

  • 查看日志:sudo docker compose logs --tail=200
  • 检查数据目录权限:ls -ln /opt/hermes(所有者应为 10000:10000
  • 确认 HERMES_BIND_ADDRtailscale ip -4 的结果一致,并且 Tailscale 处于活动状态:tailscale status
  • 如果更新后初始化时出现权限错误,可暂时注释掉 cap_drop/cap_add 块以确认问题,然后只添加缺少的 capability。

Discord 机器人在线但不回复

  • 确认 Developer Portal 中已启用 Message Content Intent
  • 确认您的用户 ID 已包含在 DISCORD_ALLOWED_USERS 中。
  • 在频道中,记得 @提及 机器人。
  • 每次修改后重启:sudo docker compose restart

“API key not set”

重新配置提供商:sudo docker compose run --rm hermes model,然后重启服务。

参考资料