在 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 就绰绰有余:
- VPS Performance - 适合个人实例
- VPS NVMe - 性价比出色
- Eco 独立服务器 - 适合多个智能体/配置文件或高强度浏览器自动化
前提条件
- root SSH 访问权限或具有 sudo 权限的用户
- Ubuntu 24.04 LTS 或 Debian 12/13 系统
- 一个模型提供商账户(例如 OpenRouter)及 API 密钥
- 一个 Tailscale 账户(个人使用免费),用于访问 Web 界面
- 一个 Discord 账户(或 Telegram、Slack…),用于与智能体对话
配置要求
| 组件 | 最低配置 | 推荐配置 |
|---|---|---|
| 内存 | 2 GB | 4 GB |
| CPU | 1 vCPU | 2 vCPU |
| 存储 | 10 GB | 20 GB |
文章作者在 2 vCPU / 2 GB 的 VPS 上运行 Hermes,但建议一旦使用浏览器自动化(Playwright/Chromium)或多个子智能体,至少配备 4 GB 内存。
浏览器控制台(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,以便访问该界面。
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
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
在向导中:
- 模型提供商:例如选择 OpenRouter 并粘贴您的 API 密钥。替代方案:使用 Nous Portal 订阅运行
hermes setup --portal(包含 300 多个模型和 Web 工具,无需管理密钥)。 - 工具:启用网页搜索和网页内容提取(见下文)。
- 即时通讯:配置 Discord(见下一节)— 这是与智能体交互的主要界面。
- 不太明白的参数可以保持默认,之后都可以修改。
密钥保存在 /opt/hermes/data/.env,配置保存在 /opt/hermes/data/config.yaml。
OpenRouter 允许为每个 API 密钥设置支出上限,并可定期重置。非常适合按用量计费的个人实例。
创建 Discord 机器人(gateway)
Gateway 是将 Hermes 连接到您的即时通讯工具的组件。Discord 是最常用的选项之一:频道和话题串可以很好地组织对话。
- 前往 Discord Developer Portal,点击 New Application。
- 在 Bot 选项卡中,启用以下 Privileged Gateway Intents,然后点击 Save Changes:
- Message Content Intent(必需:否则机器人收到的消息为空)
- Server Members Intent(必需)
- 仍在 Bot 中,点击 Reset Token 并复制令牌。
- 通过 Installation 选项卡(或 OAuth2 → URL Generator,scope 选
bot)将机器人邀请到您的 Discord 服务器。 - 获取您的 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 | 全局参数:模型、工具、审批、委派 |
.env | API 密钥(模型提供商、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
这些模型是文章撰写时给出的示例。模型格局变化很快:请根据您的预算和需求进行选择。您也可以在 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 |
在使用 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/data。state.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_ADDR与tailscale 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,然后重启服务。