ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Rocky Linux部署Hermes Agent与Web-UI:从系统初始化到反向代理的实战指南

Rocky Linux部署Hermes Agent与Web-UI:从系统初始化到反向代理的实战指南 前阵子公司新到一台测试服务器系统装的是 Rocky Linux 9.6领导点名让我把 Hermes Agent 和配套的 Hermes-Web-UI 都跑起来还要做成能直接交付给业务侧用的自托管服务。我本来想着这种开源 Agent 项目装起来不就是拉代码、装依赖、起服务三步走结果实际操作下来还是踩了不少坑尤其是 Rocky Linux 这种偏向企业级稳重的发行版跟我在 Ubuntu 上的操作习惯差别比想象中大。整个过程从裸机系统初始化到 Web 界面能正常对话、能画图折腾了一整天所以想完整记录一下给同样需要在 Rocky Linux 上部署 Hermes Agent 和 Hermes-Web-UI 的朋友做个参考。这篇文章不是那种一句话带过的快速教程我会把系统初始化、静态 IP 和软件源配置、Agent 本体安装、Web-UI 部署、反向代理、模型对接、常见故障排查都串起来讲。每个步骤我都会说清楚为什么这么做而不是只丢给你一串命令。内容适配的场景是一台刚装好 Rocky Linux 的服务器8.x 或 9.x 都可以我以 9.6 为主你手上有 root 权限目标是把 Hermes Agent 作为后台服务常驻运行并通过 Hermes-Web-UI 进行可视化管理。1. 系统落地前的三板斧静态 IP、软件源、基础依赖1.1 先给网卡配一个不会漂移的 IP很多人装完 Rocky Linux 就直接开始装软件结果重启之后 IP 变了连 SSH 都进不去更别提后面还要用 Nginx 做反向代理。这一步必须最先做。Rocky Linux 9 默认使用 NetworkManager 管理网络配置静态 IP 我建议直接用 nmcli别去手改/etc/sysconfig/network-scripts/ifcfg-*文件虽然也能改但很容易因为 NetworkManager 的配置冲突导致 network 服务起不来。先看一下当前网卡名称和连接状态nmcli device status nmcli connection show正常情况下会有类似ens160、ens192这类物理网卡名称。确认好了之后用下面的命令把连接改成静态 IP我这里用ens160举例你需要替换成你自己的网卡名和实际 IP 规划nmcli connection modify ens160 ipv4.method manual \ ipv4.addresses 192.168.10.100/24 \ ipv4.gateway 192.168.10.1 \ ipv4.dns 223.5.5.5 8.8.8.8 \ connection.autoconnect yes nmcli connection up ens160 ip addr show ens160这里我用了两组 DNS一组是国内的公共 DNS一组是通用 DNS具体怎么选看你网络环境。修改完成之后务必执行一次systemctl restart NetworkManager然后重新连 SSH 确认地址没变。如果你和我一样是双网卡机器建议把管理网卡和服务网卡分开Web-UI 监听的服务网卡后面在防火墙放行时也要单独区分。还有一个小细节Rocky Linux 9 默认开启了Predictable Network Interface Names网卡名是ens开头这和 CentOS 7 时代完全不一样了很多老教程还在用eth0照着敲命令会直接报错先nmcli device status确认名字永远不会有错。1.2 软件源配置别让网络波动耽误时间在 Rocky Linux 上装软件包我最先做的就是检查当前源是否可用。北美默认源在部分网络环境下访问真的很慢尤其是装 nodejs、python3-pip 这类比较大的包时失败概率很高。这次部署我直接把源切换到了国内镜像Rocky Linux 8.10 和 9.6 的切换方式略有不同但思路一致。Rocky Linux 9.6 的官方源默认走的是https://download.rockylinux.org/pub/rocky/我改成了镜像站源# 备份原有源配置 mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/Rocky*.repo /etc/yum.repos.d/backup/ # 写入新的仓库配置 cat /etc/yum.repos.d/rocky-mirror.repo EOF [baseos] nameRocky Linux $releasever - BaseOS baseurlhttps://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/BaseOS/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 enabled1 [appstream] nameRocky Linux $releasever - AppStream baseurlhttps://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/AppStream/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 enabled1 [extras] nameRocky Linux $releasever - Extras baseurlhttps://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/extras/$basearch/os/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 enabled1 EOF如果你是 8.10仓库结构不太一样还需要额外加PowerTools或者叫CRBCodeReady Builder的仓库否则一些编译依赖的包根本装不上。9.x 版本把这部分合并进了 AppStream情况会简单一些。源配好之后执行dnf clean all dnf makecache dnf update -y更新完系统顺手把基础工具链装上。Hermes Agent 的核心是 Python 服务Web-UI 是前后端分离的项目所以 git、gcc、make、python3、python3-pip、nodejs、npm、nginx 这些都要准备好dnf install -y git gcc gcc-c make python3 python3-pip python3-devel nodejs npm nginx python3 --version node --version npm --version如果nodejs默认版本太老Rocky 9 的 AppStream 仓库自带的 Node.js 版本是 18.x够用但不算新后面跑 Hermes-Web-UI 前端构建时可能会出现语法不支持的情况。遇到这种问题直接使用 NodeSource 提供的仓库更新版本不要自己折腾二进制包。1.3 创建专用账户不要用 root 跑服务这是一个在很多内部部署中经常被忽略的点。Hermes Agent 启动后需要读写模型缓存、日志、配置文件如果用 root 跑万一项目里有任何反弹 Shell 或者不安全的依赖注入漏洞风险会被无限放大。所以我单独创建了一个专用服务账户并规划好目录结构useradd -m -s /bin/bash hermes mkdir -p /opt/hermes/app /opt/hermes/data /opt/hermes/logs chown -R hermes:hermes /opt/hermes passwd hermes规划目录时我的习惯是/opt/hermes/app存放 Hermes Agent 和 Hermes-Web-UI 的代码文件/opt/hermes/data存放 SQLite 数据库、模型配置、上传的附件/opt/hermes/logs统一收集 Agent 和 Web-UI 的运行日志这种按功能拆分目录的做法在后面对接模型、备份数据时会非常舒服因为你只需要打包data目录就够了不用连带一大堆代码文件一起备份。2. Hermes Agent 本体安装拉代码、装依赖、配系统服务2.1 版本选择与目录初始化的讲究Hermes Agent 这个项目在 GitHub 上持续更新个人开发者和小团队最喜欢的就是它支持多种模型后端接入而且配置灵活。不过版本迭代快也意味着 Commit 之间的行为差异很大建议不要直接git clone主分支而是先打开 Release 页面选择最新的稳定 Release tag 再拉取。sudo -u hermes git clone https://github.com/hermes-agent/hermes-agent.git /opt/hermes/app/hermes-agent cd /opt/hermes/app/hermes-agent git checkout v2.x.x这里我建议/opt/hermes/app/hermes-agent作为 Agent 的主目录。项目拉取下来后第一件事不是急着装依赖而是先建好虚拟环境并确认 Python 版本兼容。Hermes Agent 在 Python 3.11 跑得最顺Rocky 9.6 自带的 Python 是 3.9官方源里没有更新的 Python所以要么用dnf module install python3.11切换到 module 流要么用pyenv安装。用 DNF module 的方式最简单直接dnf module list python3* dnf module install -y python3.11 alternatives --set python3 /usr/bin/python3.11 python3 --version安装了多个 Python 版本后一定要用alternatives命令设置默认 Python否则后续pip install和python命令可能指向不同版本排错的时候很闹心。2.2 用虚拟环境装依赖并学会看依赖输出虚拟环境这一步我强烈建议不要省因为系统级 pip 装一堆依赖后续升级或者卸载时容易出问题cd /opt/hermes/app/hermes-agent sudo -u hermes python3 -m venv venv sudo -u hermes bash -c source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt如果是在国内服务器上执行pip 下载慢或者超时是很正常的。我习惯在虚拟环境内部先设置镜像源source venv/bin/activate pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install -r requirements.txt安装过程中要留意输出中是否有error字样比如常见的Failed to build pygame或者subprocess-exited-with-error。这些基本都是缺少系统级开发库导致的像portaudio-devel、libffi-devel、openssl-devel这类缺什么补什么dnf install -y libffi-devel openssl-devel portaudio-devel项目根目录下一般会有一个.env.example或config.example.yaml把它复制成实际配置这里面是 Agent 的核心参数。我以 YAML 配置为例大致需要关注这几个字段agent: name: hermes-agent model_backend: openai_compatible model_name: deepseek-chat api_base: http://127.0.0.1:8000/v1 api_key: sk-local-fake-key temperature: 0.7 max_tokens: 2048 system_prompt: 你是一个乐于助人的本地助手 web_ui: enabled: true host: 0.0.0.0 port: 8080 allowed_origins: - http://hermes.example.com - http://localhost:3000这里的model_backend写成openai_compatible是因为 Hermes Agent 支持 OpenAI 协议兼容的接口格式不管后面接的是 DeepSeek 官方 API、本地 llama.cpp 还是 vLLM都可以用同一套配置。具体的模型对接我后面单独用一节来说。需要特别提醒如果api_key用的是本地模型的占位符Hermes Agent 在启动时也会去做一次GET /v1/models的连通性检查所以并不是配置了不存在的地址就能跳过连接本地模型服务必须先起来否则 Agent 进程会一直报连接错误。2.3 用 systemd 托管 Agent让服务“活”得更久我见过很多人在本地用nohup python run.py 起服务一锁屏或者关终端服务就没了。在服务器上跑服务正确的姿势是用 systemd。创建一个 service 文件让开机自启、崩溃自动拉起都交给系统管cat /etc/systemd/system/hermes-agent.service EOF [Unit] DescriptionHermes Agent Service Afternetwork-online.target Wantsnetwork-online.target [Service] Userhermes Grouphermes WorkingDirectory/opt/hermes/app/hermes-agent EnvironmentPATH/opt/hermes/app/hermes-agent/venv/bin ExecStart/opt/hermes/app/hermes-agent/venv/bin/python run.py Restartalways RestartSec5 LimitNOFILE65535 [Install] WantedBymulti-user.target EOF systemctl daemon-reload systemctl enable --now hermes-agent systemctl status hermes-agent有个小坑要提前说如果 Agent 的配置文件里有敏感信息api_key 或 tokensystemd 服务的运行环境变量不适合放这些机密内容直接把配置写在项目目录下的.env文件里然后通过配置文件读取保证密钥权限是640并且属主是hermes用户就好。启动之后用journalctl -u hermes-agent -f实时看日志确认没有异常报错。正常启动会看到监听端口和模型连接成功的日志这就说明 Agent 本体已经跑起来了。3. Hermes-Web-UI 部署从构建到反向代理3.1 直接跑还是要容器化我的选择逻辑Hermes-Web-UI 是提供给用户操作的可视化界面本质上是一个独立的前后端项目它默认监听一个端口并通过 WebSocket 与 Agent 保持长连接。部署方式主要有两种Docker Compose 方式和裸机方式。Docker 方式的优点是环境隔离、依赖不污染宿主机缺点是在部分内网环境拉取镜像需要额外操作。裸机方式的好处是资源占用小、调试方便缺点是需要手动管 Node 服务。这次我选择的是裸机方式因为服务器上已经装了 Node.js 18而且 Hermes-Web-UI 本身没有太多重量级系统依赖没必要再引入 Docker 这一层。如果你要在一台机器上同时部署多个 Agent 实例那 Dcoker Compose 会是更合适的方案端口和资源能隔离得更干净。先拉取 Web-UI 代码sudo -u hermes git clone https://github.com/hermes-agent/hermes-web-ui.git /opt/hermes/app/hermes-web-ui cd /opt/hermes/app/hermes-web-ui npm install如果 npm 安装依赖时卡在node-gyp或者electron这种二进制构建阶段先设置镜像源再重试npm config set registry https://registry.npmmirror.com npm install安装完成之后检查项目根目录下有没有.env文件Web-UI 通常需要知道 Agent 的 API 地址和 WebSocket 地址配置大致是这样VUE_APP_API_BASEhttp://127.0.0.1:8080/api VUE_APP_WS_BASEws://127.0.0.1:8080/ws VUE_APP_PORT3000注意这里VUE_APP_API_BASE是从浏览器端发起的请求地址所以不能写127.0.0.1除非你是在服务器本机访问。我用的是域名就写http://hermes.example.com/apiWebSocket 地址对应写ws://hermes.example.com/ws。构建生产版本npm run build npm run start本地验证一下 3000 端口是否起来再结合 Nginx 做反向代理就能正式对外提供服务了。3.2 Nginx 反向代理时最容易栽的 WebSocket 坑开发模式下直接用3000端口访问没问题但交付给业务侧使用时总不能让他们记住http://IP:3000这种地址。我的习惯是统一用 80/443 端口加域名访问用 Nginx 做反向代理。配置里最核心的就是 WebSocket 的 Upgrade 头我在第一次配的时候就漏了结果页面能打开但发消息始终没响应还以为是 Hermes Agent 挂了。以下是 Nginx 配置重点在/ws路径的proxy_set_header Upgradeserver { listen 80; server_name hermes.example.com; access_log /var/log/nginx/hermes-web-ui.access.log; error_log /var/log/nginx/hermes-web-ui.error.log; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /ws { proxy_pass http://127.0.0.1:3000/ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } location /api { proxy_pass http://127.0.0.1:8080/api; proxy_http_version 1.1; proxy_set_header Host $host; } }proxy_read_timeout和proxy_send_timeout设成 3600 秒是我建议加的因为 Agent 生成长文本回答时单个请求超过 60 秒很常见如果不调大超时时间Nginx 会在中途断开连接前端拿到不完整的结果。这个参数配置不写等用户问一个长问题时就会暴露问题。配置好之后nginx -t systemctl reload nginx如果访问时发现静态资源加载 404多半是VUE_APP_API_BASE环境变量配置和 Nginx 的location路径没对齐导致前端打包时接口请求路径是/api而 Nginx 转发的是/api/这类问题直接看浏览器 Network 面板即可定位。3.3 防火墙和 SELinux两个一不留神就拦路的角色Rocky Linux 默认开了 firewalld也开启了 SELinux。很多人部署完服务发现外部访问不了第一反应是 Nginx 配置错了其实可能只是防火墙没有放行端口。放行 HTTP/HTTPS 端口systemctl status firewalld firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --permanent --add-port3000/tcp firewall-cmd --reload firewall-cmd --list-all如果你要直接让用户访问8080或3000端口记得也要放行对应端口但我个人建议只放行 80/443其他服务一律走 Nginx 反代这样对外开放的端口面最小。SELinux 这边Nginx 默认只能访问/usr/share/nginx/html等几个特定目录如果网站根目录或代理目标涉及自定义路径就会报Permission denied。最简单的排查方式是把 SELinux 临时设为 permissive 看问题是否消失setenforce 0如果确认是 SELinux 拦截不要图省事直接禁用而是给 Nginx 开放对应网络权限setsebool -P httpd_can_network_connect 1这个布尔值对于反向代理场景是必须开启的否则 Nginx 无法向后端服务发起网络连接。对于反向代理到非标准端口的情况这一步尤其重要。如果想要更精细的话可以用audit2allow根据/var/log/audit/audit.log里面的 AVc 拒绝记录生成自定义策略但对多数部署场景开启httpd_can_network_connect已经足够。4. 对接外部能力本地模型、draw.io 与常用扩展配置4.1 给 Hermes Agent 接上本地 DeepSeek 模型很多人部署 Agent 后用的还是外部 API但我这次接的是本地 DeepSeek 模型服务。需要提示的是我这里说的本地是指同一内网里的 GPU 服务器。生产环境不建议把模型服务和 Agent 装在同一台机器Agent 和 Web-UI 已经占掉不少内存了再跑一个大模型推理性能压力会很大。在安装 Hermes Agent 前先把本地模型服务用 vLLM 或 llama.cpp 跑起来。以 vLLM 启动 DeepSeek 模型为例模型服务监听在8000端口python -m vllm.entrypoints.openai.api_server \ --model /opt/models/deepseek-v2-chat \ --served-model-name deepseek-chat \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 2启动完成后Hermes Agent 的配置就指向这个地址。如果你的模型走的是 OpenAI 兼容协议配置大概是这样的model: backend: openai_compatible base_url: http://192.168.10.20:8000/v1 api_key: not-needed-for-local model: deepseek-chat temperature: 0.8 max_tokens: 4096在没用正式 key 的情况下很多本地推理服务会把api_key当成占位字段但请求头里仍然需要带上它。如果发现 Agent 日志里有401 Unauthorized就把api_key改成任意非空字符串试试。这里有个实用的测试方法curl http://192.168.10.20:8000/v1/models能返回模型列表说明模型服务正常。再用一次简单的chat/completions请求验证是否能正常生成回答能通再检查 Agent 侧配置否则就是模型服务自身的问题别让 Agent 背锅。大模型服务的显存占用是动态的建议给模型服务设置--max-model-len参数限制最大序列长度防止长对话把显存打爆之后整机卡死。4.2 在 Web-UI 里集成 draw.io我注意到你在热搜词里提到了next ai draw.io 是否支持与 hermes agent 对接这个问题在社区里也有不少人问。直接说结论Hermes-Web-UI 目前没有原生内置 draw.io但可以通过 iframe 嵌入方式把 draw.io 集成进来效果上等于在界面里多了一个可以画流程图的工具页。实现方式有两种看你想要的效果第一种是把官方 draw.io 嵌入为 iframe在 Web-UI 的某个菜单里增加一个外部链接菜单iframe srchttps://embed.diagrams.net/?uisketchchrome0edit_blank stylewidth: 100%; height: calc(100vh - 60px); border: none; /iframe这种方式的集成成本最低五分钟就能搞定但要求服务器能访问外网。如果你在内网环境需要搭一个内网可访问的 draw.io 镜像服务然后把 iframe 地址改成内网的地址。第二种灵活一些结合 Hermes Agent 的能力让 Agent 在生成图表内容时直接输出 draw.io 可识别的.drawioXML 文件。draw.io 的文件本质上是 XML你可以引导 Agent 生成结构化的 XML然后在前端界面提供一个打开draw.io的链接把 XML 数据通过 URL 参数传给 draw.io 编辑器。具体在 Web-UI 代码中可以加一个简单的路由/drawio渲染 iframe 时动态读取 URL 中的xml参数const url https://embed.diagrams.net/?uisketchchrome0#R${encodeURIComponent(xmlData)};后者是真正意义上Agent 生成流程图、然后交给 draw.io 渲染的闭环方案也是我觉得最实用的一种方式。目前社区已经有相关的插件在做了如果你需要这个功能可以自己在 Web-UI 中加一个 Toolbar 按钮实现。4.3 其他值得调整的扩展配置Hermes Agent 除了模型参数外还有几个跟实际交付关系比较大的配置点这里一起列出来。对话历史存储默认情况下历史对话放在本地data目录里。如果用户量大建议后端换成 PostgreSQL在配置里把storage.type改成postgresql并填连接串。这个改动需要提前建库不过换来的是并发读写能力和更大的存储上限。日志切片与清理日志文件如果不处理几个月下来能到几个 GB。在 systemd service 里加上LogRotate相关的配置或者直接给日志目录配置 logrotatecat /etc/logrotate.d/hermes EOF /opt/hermes/logs/*.log { daily rotate 7 compress missingok notifempty copytruncate } EOF这个配置放到生产环境很有用因为我见过不少服务器就是日志把磁盘写满然后 Agent 神秘宕机的。多 Agent 实例Hermes Agent 本身设计上支持一个实例为主如果你想跑多个不同角色的 Agent比如一个做代码助手一个做知识库问答建议用 Docker Compose 分别起两套服务通过环境变量隔离端口和模型配置。裸机方式也可以但需要手动改端口和 systemd 服务名比较繁琐。5. 从零排障我实际遇到的三类最典型的坑5.1 Agent 端口起不来先查这几步再动手第一次部署时我执行完 systemctl start 后发现服务状态是active (running)但端口就是不通。用ss -lntp | grep 8080看根本没有进程监听。第一步要查的其实不是防火墙而是进程到底有没有起来journalctl -u hermes-agent -n 50 --no-pager日志里多半会显示某个模块导入失败比如ModuleNotFoundError: No module named xxx。大部分情况是虚拟环境的依赖没装全或者是系统里同时存在多个 Python 版本导致 pip 装错了环境。第二步查的是端口冲突用ss -lntp看看8080是不是被别的进程占了如果被占了改配置里的端口再重启。第三步才是防火墙放行问题。简单总结排查顺序服务状态与日志journalctl进程与端口ss -lntp本机自测curl 127.0.0.1:8080防火墙与 SELinuxNginx 日志这个顺序可以帮你在最短时间内定位问题而不是一上来就怀疑网络层配置。5.2 数据库连接失败往往不是数据库的问题有一次我把 Agent 的存储从 SQLite 切到 PostgreSQL按照网上的配置改好连接串结果启动时一直报connect: connection refused。我一开始怀疑是 PostgreSQL 没起来查了之后发现服务正常端口也通最后才发现是连接串里的主机名写的是localhost而 PostgreSQL 的pg_hba.conf只允许127.0.0.1连接。这个经历给了我一个教训遇到连接类错误先用命令行工具实测连接再回头看应用程序的配置。比如 PostgreSQL 就用psql -h 127.0.0.1 -U hermes -d hermesdb -c select 1;如果命令行能连但应用连不上那就是应用层配置问题如果命令行也连不上再查权限和监听地址。另外PostgreSQL 默认监听localhost如果数据库和应用不在同一台机器需要去/var/lib/pgsql/data/postgresql.conf里把listen_addresses改成*否则远端永远连不上。5.3 页面能打开但功能不动罪魁祸首多半是 WebSocket这个坑我前面提过但值得单独说一次。Web 页面能正常打开说明 HTTP 服务没问题但发消息没反应、内容一直不刷新说明 WebSocket 被中间层拦了。定位方法很简单打开浏览器开发者工具切到 Network 面板刷新页面然后看WS类型的请求正常情况下会看到一条101 Switching Protocols的状态码。如果看到403、502或者一直 pending说明 WebSocket 握手失败了。Nginx 方向重点检查proxy_set_header Upgrade和proxy_set_header Connection upgrade这两行。再就是确认 Web-UI 前端代码里配置的 WebSocket 地址确实指向后端的/ws路径如果地址末尾少个/ws也会出现握手失败。如果 Nginx 配置没问题再查一下防火墙有没有拦8080或3000端口。WebSocket 握手是通过 HTTP 升级实现的所以本质上依然是 TCP 连接如果中间防火墙对长连接做了限制比如 60 秒无数据就断开那也需要在 Nginx 的proxy_read_timeout上做调整。6. 部署完成后这套系统实际跑下来的表现6.1 资源占用和稳定性实测整套系统跑在 Rocky Linux 9.6 上配置是 4 核 8G 内存的虚拟机Agent 和 Web-UI 以及 Nginx 都在这台机器上。默认情况下Hermes Agent 进程占用内存约 400MB 左右Web-UI 的 Node 服务占用约 150MB整体占用在 600MB 以内这个开销对于企业内部的业务服务器来说完全可以接受。让我比较满意的是 systemd 托管后的稳定性服务跑了一周多没有出现过掉线。中途我手动 kill 过一次 Agent 进程设定Restartalways后 5 秒内自动拉起来了Web-UI 通过 WebSocket 自动重连用户基本无感知。模型服务单独跑在另一台 GPU 机器上走的内网 API接口响应速度比外网 API 稳定很多。DeepSeek 模型做对话问答、代码生成配上 Hermes-Web-UI 的界面体验上跟在用的商业 AI 助手已经很接近了。6.2 绑定开机启动最后的交付清理部署完成后一定要确认所有服务在服务器重启后都能自己起来systemctl enable --now hermes-agent systemctl enable --now nginx systemctl enable --now node-web-ui # 如果 Web-UI 也用 systemd 托管的话Web-UI 用 systemd 托管的话可以仿照 Agent 的方式写一个 service 文件ExecStart 用node直接指向构建产物目录下的 server 入口文件。交付前最后再检查几件事配置文件的属主和权限确认机密配置不是777日志轮转是否生效防火墙只对外开放必要的端口SELinux 保持 enforcing 状态数据目录SQLite 或 PostgreSQL做一次备份测试这些做完之后整个部署就算真正闭环了而不是能跑就行的状态。最后分享一个我在实际维护中的体会Rocky Linux 和 Ubuntu 在部署这类开源项目时最大的差异其实不在安装命令而在系统级约束SELinux、firewalld、软件源上。你只要在操作前把这三板斧处理好后续的安装流程会比想象中顺很多。这次部署用到的所有配置和排障思路基本都是我实际踩过坑之后整理出来的希望能帮你省下一些时间。如果你也在 Rocky Linux 上跑 Hermes Agent或者集成 draw.io 时有什么更好玩的方案欢迎随时交流。
返回列表