
前段时间帮朋友在一台 Rocky Linux 服务器上部署 Hermes Agent 和 Hermes-Web-UI折腾了一下午踩了不少坑也把整个安装链路摸透了。这里把完整过程整理出来给准备在 Rocky Linux 上跑 Hermes Agent 的同学一个可以直接照抄的参考。先说清楚这组东西是干什么的。Hermes Agent 是一个本地部署的任务执行型智能体框架它负责接收指令、调度工具、对接模型 API并把任务结果统一返回Hermes-Web-UI 则是它的可视化控制台用来管理 Agent 配置、查看运行日志、下发任务。服务端跑在 Linux 上最稳尤其像 Rocky Linux 这种企业级发行版生命周期长、软件源规范适合当常驻服务。这篇文章我会从系统初始化讲起包括静态 IP 配置、YUM 源切换、运行时依赖安装再到 Agent 核心、Web UI、Nginx 反向代理、systemd 守护进程最后把常见的坑也列出来。无论你是刚接触 Rocky Linux 的新手还是已经跑过其他服务的老手都能在这篇文章里找到对应的操作。1. 部署思路与方案选型1.1 Hermes Agent 在服务器上到底跑什么我在最初看这个项目的时候第一反应也是想知道它在服务器上到底由哪些部分组成。实际拆开来看主要就三个东西Agent 核心、调度执行器、Web 控制台。Agent 核心是负责理解任务和分发任务的程序一般以常驻服务的形式运行监听一个本地端口。调度执行器处理具体的工具调用包括执行 Shell 命令、读写文件、调用 HTTP 接口、和模型 API 通信等。Hermes-Web-UI 则是另一套独立服务负责把用户的操作界面和 Agent 的接口连接起来。我部署的时候习惯把它们放在同一台机器上Agent 监听内网端口Web UI 在前面用 Nginx 反向代理这样对外只暴露一个 Web 端口内部调用链清晰也方便排查问题。如果团队里有统一认证网关后续还可以把 UI 服务接到网关后面权限控制更省心。1.2 为什么选 Rocky Linux版本怎么选我自己平时 Linux 服务器用 Debian 和 CentOS 系比较多这次选择 Rocky Linux 纯粹是从生产环境稳定性考虑的。Rocky Linux 和 CentOS 保持二进制兼容迁移成本低官方支持周期也长跑 Hermes Agent 这种需要长期常驻的服务很合适。版本上Rocky Linux 8.10 和 9.6 都有人用。我的建议是如果是新装系统优先选 9.xPython、Node.js、OpenSSL 这些基础组件的新版支持更好如果机器上已经有 8.10 的业务环境也没必要为了 Hermes Agent 强行换系统8.10 配置好 YUM 源后同样能跑。这篇文章里的命令在 8.10 和 9.6 上基本通用个别地方我会标注差异。还有一点网上能搜到 Hermes Agent 的 Windows 本地部署教程但我还是一贯建议服务端和 Agent 核心尽量跑在 Linux 上Windows 当客户端管理终端可以常驻服务的稳定性还是 Linux 更可靠。2. 系统初始化静态 IP 和 YUM 源这一步看起来和 Hermes Agent 没什么直接关系但我在实际操作中吃过亏系统装完是 DHCP 获取地址重启后 IP 变了Web 界面访问不到还以为服务挂了。所以先把静态 IP 固定下来再配置好软件源后面安装依赖才会顺。2.1 用 nmcli 给 Rocky Linux 设置静态 IPRocky Linux 默认使用 NetworkManager 管理网络命令行下用 nmcli 最方便不需要重启 NetworkManager直接生效。先查看当前网络连接名nmcli connection show一般会看到一个类似 ens160 或 ens3 的 connection记住那个 NAME下面把它改成静态 IP。假设我要把 IP 配成 192.168.10.50网关 192.168.10.1DNS 用 223.5.5.5 和 114.114.114.114命令如下nmcli connection modify ens160 ipv4.method manual \ ipv4.addresses 192.168.10.50/24 \ ipv4.gateway 192.168.10.1 \ ipv4.dns 223.5.5.5 114.114.114.114 nmcli connection up ens160这条命令会自动把 NetworkManager 的配置文件改好。执行完以后用ip addr和ip route验证 IP 和网关是否生效。这里有几个小细节虚拟机网卡如果是 NAT 模式网关地址别填错如果服务器是通过远程连接的改静态 IP 前最好确认管理口的 IP 段避免把自己锁在门外。改完后顺手把主机名也设一下让 Hermes 日志更容易分辨hostnamectl set-hostname hermes-server2.2 给 Rocky Linux 8.10 和 9.6 配置 YUM 源国内服务器直接访问官方源经常慢到怀疑人生装个 Python 依赖能卡半天。我把源切换成了国内镜像源这里以 Rocky 官方仓库 阿里云镜像为例8.10 和 9.6 的操作逻辑一样。先备份原始仓库文件mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/然后新建一个 BaseOS 和应用流仓库文件cat /etc/yum.repos.d/Rocky-Mirror.repo EOF [baseos] nameRocky Linux $releasever - BaseOS baseurlhttps://mirrors.aliyun.com/rockylinux/$releasever/BaseOS/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever enabled1 [appstream] nameRocky Linux $releasever - AppStream baseurlhttps://mirrors.aliyun.com/rockylinux/$releasever/AppStream/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever enabled1 [extras] nameRocky Linux $releasever - Extras baseurlhttps://mirrors.aliyun.com/rockylinux/$releasever/extras/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever enabled1 EOF在 Rocky 9.x 里还建议加一个 CRB 仓库很多编译依赖和扩展包都在这里cat /etc/yum.repos.d/Rocky-CRB.repo EOF [crb] nameRocky Linux $releasever - CRB baseurlhttps://mirrors.aliyun.com/rockylinux/$releasever/CRB/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever enabled1 EOF然后刷新缓存dnf clean all dnf makecache dnf repolist看到 baseos、appstream 都正常列出源就配置好了。再说一句$releasever这个变量会自动匹配当前系统版本8.10 和 9.6 都能用同一个仓库文件不需要每个版本单独写死版本号。3. 安装 Hermes Agent 核心3.1 安装运行时依赖Python、Node.js、Git、DockerHermes Agent 的依赖里Python 环境是跑核心逻辑的Node.js 在构建 Web UI 时要用到Git 用来拉取代码Docker 不是必须的但如果 Agent 需要隔离执行外部工具Docker 会省很多事。Rocky Linux 8.10 默认带的 Python 3.6 偏老建议启用 Python 3.9 模块dnf module enable -y python39 dnf install -y python39 python39-devel python39-pipRocky 9.x 默认就有 Python 3.9 以上直接装 python3 和 python3-devel 就行。我们后面创建虚拟环境时建议明确指定python3.9避免系统里多个 Python 版本造成混淆。Node.js 用 NodeSource 仓库安装 LTS 版本这里以 Node.js 20 为例curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - dnf install -y nodejs如果网络限制访问不了 NodeSource也可以下载离线 tar.xz 包解压后用软链方式配置但步骤会多一点。安装完用node -v和npm -v验证。Git 和 Docker 一条命令装好dnf install -y git docker-ce docker-ce-cli containerd.io systemctl enable --now docker这里要留意Docker 官方仓库需要先配置如果你在 yum 里找不到 docker-ce就检查一下是否已经添加 Docker 官方 repo。不想折腾 Docker 的装个 Podman 也能凑合但很多容器编排脚本默认写的是 docker 命令所以我还是装了 Docker。3.2 获取 Hermes Agent 代码并创建虚拟环境我建议把项目放到/opt/hermes这个统一目录下方便管理权限和备份。先确认官方发布的最新稳定版本然后用 Git 克隆到指定版本分支git clone https://github.com/your-repo/hermes-agent.git /opt/hermes cd /opt/hermes git checkout v1.2.0 # 换成实际需要的版本号拿到代码后创建 Python 虚拟环境把依赖装进去python3.9 -m venv /opt/hermes/.venv source /opt/hermes/.venv/bin/activate pip install --upgrade pip pip install -r requirements.txt如果你的服务器访问 PyPI 慢可以在 pip 命令里指定清华源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple依赖安装完成后先别急着启动。Hermes Agent 一般会有一个初始化命令用于生成配置文件和初始化数据库我这边执行的是hermes init hermes migrate初始化的时候会让你填 Agent 名称、端口、数据库连接串、模型 API 地址等信息。如果没有交互式引导也可以手动创建.env文件下面是我常用的最小配置模板HERMES_HOME/opt/hermes HERMES_PORT8901 DATABASE_URLsqlite:////opt/hermes/data/hermes.db MODEL_API_BASEhttp://127.0.0.1:8000/v1 MODEL_API_KEYyour-api-key LOG_LEVELinfoMODEL_API_BASE这个变量很关键它决定了 Agent 调用哪个模型的接口。如果本地已经跑了一个兼容 OpenAI 协议的模型服务比如 vLLM、Ollama 或 DeepSeek 的本地部署把地址指过去就行如果暂时不想接模型也可以先用 mock 模式跑通流程。3.3 启动 Agent 并注册成 systemd 服务初始化完成后先在终端前台跑一下确认服务能正常起来cd /opt/hermes source /opt/hermes/.venv/bin/activate hermes start看到类似Uvicorn running on http://0.0.0.0:8901的日志说明 Agent 监听端口正常。这时候可以另开一个终端用 curl 探一下curl http://127.0.0.1:8901/health返回 JSON 结构体、包含 status 状态字段说明健康检查通过。如果一切正常CtrlC 停掉前台进程写 systemd 服务让它在后台稳定运行cat /etc/systemd/system/hermes-agent.service EOF [Unit] DescriptionHermes Agent Service Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple Userhermes Grouphermes WorkingDirectory/opt/hermes ExecStart/opt/hermes/.venv/bin/hermes start Restarton-failure RestartSec5 EnvironmentFile/opt/hermes/.env [Install] WantedBymulti-user.target EOF记得先创建独立用户不要用 root 跑生产服务useradd -r -s /sbin/nologin -d /opt/hermes hermes chown -R hermes:hermes /opt/hermes然后启动服务systemctl daemon-reload systemctl enable --now hermes-agent systemctl status hermes-agent到这里Hermes Agent 核心已经是开机自启的常驻服务了。如果你看到服务一直 Restart先看日志journalctl -u hermes-agent -f大多数情况是.env里的路径或权限不对用日志里给的报错信息定位就行。4. 安装与配置 Hermes-Web-UI4.1 用静态文件构建 Hermes-Web-UIHermes-Web-UI 前端是一个独立的工程通常和 Agent 仓库分开管理。把前端代码拉到/opt/hermes-web安装依赖并构建git clone https://github.com/your-repo/hermes-web-ui.git /opt/hermes-web cd /opt/hermes-web npm install npm run build构建完成后静态文件会输出到dist/目录。把这个目录放到 Web 服务器能访问的位置我用的是系统默认 Web 根目录mkdir -p /var/www/hermes-web cp -r /opt/hermes-web/dist/* /var/www/hermes-web/ chown -R nginx:nginx /var/www/hermes-web这里要说一下为什么不用直接让 Hermes-Web-UI 前端源码跑一个 Node 开发服务而是非要构建静态文件再交给 Nginx。生产环境下 Node 开发服务器本身并不适合直接对外提供服务性能、安全、日志都不够用。Nginx 处理静态文件非常高效而且能统一管理反向代理和 HTTPS 证书后面接网关、做限流、挂 CDN 都很方便。4.2 Nginx 反向代理和 WebSocket 配置Hermes-Web-UI 界面会通过/api路径访问 Agent 后端同时 Agent 任务日志推送通常会用 WebSocket所以 Nginx 配置里需要把普通 HTTP 和 WebSocket 升级都处理好。安装 Nginxdnf install -y nginx新增一个站点配置文件/etc/nginx/conf.d/hermes.conf示例内容如下server { listen 80; server_name hermes.example.com; root /var/www/hermes-web; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8901; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /ws/ { proxy_pass http://127.0.0.1:8901; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; } }这里有个容易踩的坑location /api/后面如果带斜杠且结尾有/nginx 转发时会自动把/api前缀去掉如果后端接口地址不需要去掉前缀就要写proxy_pass http://127.0.0.1:8901/;或者用proxy_pass_request_headers组合调整。我的做法是在后端 Agent 的监听地址里直接保留/api前缀这样就能避免路径重写带来的混乱。配置好后检查语法并加载nginx -t systemctl enable --now nginx防火墙放行端口firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --reload4.3 打通 Web UI 和 Agent 之间的配置UI 构建完只是静态页面还需要让前端知道 Agent 的地址。通常 Hermes-Web-UI 在构建时可以指定环境变量比如npm run build -- --env API_BASE_URL/api如果前端写死了后端地址也可以在 Nginx 里通过注入 JS 全局变量或反向代理的方式处理我倾向直接在构建时指定/api相对路径这样不管后面怎么换域名都不用重新改前端代码。全部部署完成后浏览器访问http://服务器IP/看到 Hermes-Web-UI 登录页就说明前端正常。首次登录后到系统设置里检查 Agent 连接状态正常情况下能看到 Agent 的版本和健康状态。如果连接失败先确认/api/health是否能通过 Nginx 访问到 Agentcurl http://127.0.0.1/api/health如果有响应但 UI 还是报错打开浏览器开发者工具看接口状态码和返回信息。绝大多数情况下是 WebSocket 路径没配对或者在 Nginx 配置里丢了 Upgrade 请求头。5. 常见问题与排查技巧实录5.1 服务起不来或端口被占用Hermes Agent 默认监听 8901 端口如果之前测试时启动过老进程端口一直被占着systemd 服务会一直失败。排查命令ss -lntp | grep 8901找到占用进程后按需停掉或者直接杀掉kill -9 进程PID再重启服务systemctl restart hermes-agent如果端口没问题看日志journalctl -u hermes-agent -n 50 --no-pager常见的还有.env里HERMES_HOME路径配错导致 Agent 找不到配置文件启动直接报错。这个用日志一眼就能看出来路径改成/opt/hermes并确认目录存在就行。5.2 Web UI 白屏或接口 502白屏一般分两种情况一种是你直接访问 IP 或域名时 Nginx 主页能出来但刷新后 404这是单页应用路由问题需要在 Nginx 里加try_files $uri $uri/ /index.html;这个我在上面的配置已经写了。另一种是接口 502说明 Nginx 能访问到但 Nginx 到 Agent 的链路断了。先确认 Agent 服务在跑systemctl status hermes-agent curl http://127.0.0.1:8901/health如果本机 curl 正常那就是 Nginx 配置里的proxy_pass地址或端口写错了检查一下是不是把端口写成 UI 前端的 80或者把 host 写成外网 IP。还有一个很隐蔽的问题Agent 的监听地址默认为127.0.0.1但 Nginx 在本机用127.0.0.1去访问是没问题的如果你 Web UI 部署在另一台机器Agent 就必须监听0.0.0.0否则跨主机访问直接 Connection refused。生产环境建议根据访问关系来设置监听地址不要盲目全0.0.0.0。5.3 模型 API 连接不上Hermes Agent 在跑实际任务时需要调用模型接口。很多时候 Agent 本身启动正常Web UI 也正常但下发任务就报错日志里出现Connection refused或Timeout。这里要分场景排查如果模型服务是异步并发加载的启动需要时间第一两次调用刚好碰上模型还没 ready就会超时如果模型服务在另一台机器检查防火墙和监听地址。我在配置.env时习惯把MODEL_API_BASE单独拆出来不写死端口这样后面切换模型部署时只改这一处。另外一个容易忽略的问题是模型 API 的路径。某些本地框架的接口是/v1/chat/completions有些是/v1/completionsHermes Agent 在调用时默认走 OpenAI 兼容路径。如果你用的服务不兼容 OpenAI 协议就得先加一层适配服务否则 Agent 始终拿不到结果。网上很多人把这个问题误判成认证不对其实多看几行日志就明白了。5.4 YUM 源报错和 DNS 解析问题Rocky Linux 配置完镜像源后dnf install经常遇到Could not resolve host: mirrors.aliyun.com这说明 DNS 没配好。用nmcli重新设置 DNSnmcli connection modify ens160 ipv4.dns 223.5.5.5 114.114.114.114 nmcli connection up ens160如果系统里还有 NetworkManager 和 systemd-resolved 冲突的情况可以临时修改/etc/resolv.conf验证echo nameserver 223.5.5.5 /etc/resolv.conf重启网络后如果/etc/resolv.conf被重置那就说明 NetworkManager 还在管理 DNS用 nmcli 修改才是根治方法。配合dnf repolist和ping mirrors.aliyun.com一起验证能快速定位是仓库配置问题还是网络问题。关于 YUM 源还有一点特别想提醒不要同时启用多个相同仓库来源。我之前在一台机器上既留了官方源又加了阿里云源结果dnf有时候会从不同源拉取到不同版本的 RPM安装包版本冲突非常折腾。配置完源以后尽量用dnf repolist --enabled检查一次只保留你需要的仓库。6. 部署完之后的几点实操心得最后聊几个我在真实环境里反复踩过、后来特意记住的细节。第一.env文件一定要做备份。Hermes Agent 和 Web UI 的配置都集中在这个文件里系统重装或者目录迁移时只要有这个文件恢复服务就是几分钟的事。我一般会把它单独 clone 到一个 git 私有仓库或者用rsync定时同步到备份机。第二日志是排查问题的最好入口。Hermes Agent 的 systemd 日志会记录每一次任务的输入输出Web UI 的 Nginx 访问日志能看到前端所有接口调用情况。遇到问题先看日志不要一上来就重启服务否则可能把现场信息弄丢。我习惯在journalctl后面加-f实时追踪再结合 UI 里的任务列表一起判断。第三升级前先快照或备份数据库。Hermes Agent 的数据库文件默认在/opt/hermes/data/hermes.db这个文件记录了任务历史、Agent 配置和 Web UI 的账号信息。升级版本前用sqlite3 /opt/hermes/data/hermes.db .backup /opt/hermes/backup-$(date %F).db做个备份万一新版本有问题回滚也非常快。第四如果打算长期跑建议把 Agent 的监听地址收敛到内网再用 Nginx 对外统一暴露。这样既方便管理 TLS 证书也能屏蔽掉一些不必要的端口扫描。Web UI 登录页最好加个强密码毕竟能控制 Agent 就意味着能在服务器上执行任务权限边界要把握好。这套部署流程我后来又在一台 Rocky Linux 9.6 上重新走了一遍基本没有偏差只要把版本号替换成当前实际版本就能顺利跑通。希望这篇指南能让你少走一些弯路尤其是在静态 IP、YUM 源和 Nginx 代理这三个环节提前避坑会顺畅很多。