1. 为什么 Hermes Agent 的部署值得单独写一篇
Hermes Agent 这个项目最近在圈子里讨论度很高,但真正动手部署过的人都知道,它的环境配置比一般的工具类项目要复杂一些。原因不复杂:它同时涉及本地开发环境、容器运行时、网络端口映射、服务保活等多个环节,任何一个环节出问题,服务都起不来。我前后在 Windows 和 Linux 上部署过五六次,踩过的坑包括 WSL2 网络模式选错导致端口不通、云服务器安全组没放行、Docker 镜像拉取超时、systemd 服务写错路径导致反复重启等等。
这篇内容就是把这些经验整理出来,给准备上手 Hermes Agent 的人一条清晰的路径。不管你是用 Windows + WSL2 做本地开发调试,还是直接买一台云服务器做长期运行,都能找到对应的操作步骤。文章会覆盖 WSL2 安装与配置、云服务器选型与初始化、Docker 环境搭建、Hermes Agent 服务启动、状态校验、常见故障排查这几个核心环节。每个步骤我都会说明为什么这么做,以及不做会出什么问题。
适合的读者:有基本 Linux 命令行操作经验,了解 Docker 基本概念,想在本地或云端跑起 Hermes Agent 服务的开发者。完全没接触过 WSL2 也没关系,安装部分我会写得足够细。
2. 本地环境方案选型:为什么是 WSL2 而不是虚拟机或双系统
2.1 WSL2 与虚拟机、双系统的对比
在 Windows 上跑 Hermes Agent,常见的选择有三种:VMware/VirtualBox 虚拟机、双系统、WSL2。我三种都用过,最终长期留在 WSL2 上,原因如下。
虚拟机方案的问题是资源占用高。你开一个 Ubuntu 虚拟机,至少吃掉 2GB 内存和 20GB 磁盘,而且文件系统是隔离的,想在 Windows 和 Linux 之间共享代码需要配置共享文件夹,性能损耗明显。双系统更麻烦,切换要重启,开发效率极低。
WSL2 的优势在于它是 Windows 内核支持的轻量级虚拟化方案,启动速度快,内存按需分配,文件系统可以直接通过/mnt/c/访问 Windows 盘符。更重要的是,WSL2 支持 systemd,这意味着你可以在里面跑 Docker、配置服务自启,体验和原生 Linux 几乎一致。
注意:WSL2 和 WSL1 有本质区别。WSL1 是系统调用翻译层,很多 Docker 相关功能跑不起来。Hermes Agent 的部署必须用 WSL2,不要用 WSL1。
2.2 WSL2 的版本要求与前置检查
WSL2 对 Windows 版本有要求。Windows 10 需要 1903 及以上版本(内部版本 18362 以上),Windows 11 全版本支持。检查方法很简单,按Win + R输入winver,看版本号。
另外需要确认 CPU 虚拟化已开启。任务管理器 → 性能 → CPU,看右下角“虚拟化”是否显示“已启用”。如果显示“已禁用”,需要进 BIOS 开启 Intel VT-x 或 AMD-V。这一步很多人会忽略,结果 WSL2 装完启动报错。
还有一个容易踩的坑:如果你的系统装过 WSL1,需要先卸载旧版本再装 WSL2,否则可能出现版本冲突。卸载命令是wsl --unregister <发行版名称>,注意这会删除该发行版内的所有数据。
2.3 安装 WSL2 与 Ubuntu 22.04 的完整步骤
我推荐用 Ubuntu 22.04 LTS,原因是它的软件源稳定,Docker 官方支持好,社区资料多。Ubuntu 24.04 也可以,但部分第三方工具的兼容性还在跟进中。
安装步骤:
- 以管理员身份打开 PowerShell,执行
wsl --install。这条命令会自动启用虚拟机平台和 WSL 功能,并安装默认的 Ubuntu 发行版。 - 如果只想装 Ubuntu 22.04,先执行
wsl --list --online查看可用发行版,然后执行wsl --install -d Ubuntu-22.04。 - 安装完成后重启电脑。重启后 Ubuntu 会自动启动,要求设置用户名和密码。这个密码是 sudo 密码,记牢。
- 验证版本:执行
wsl -l -v,确认 Ubuntu-22.04 的 VERSION 显示为 2。如果显示 1,执行wsl --set-version Ubuntu-22.04 2转换。
提示:如果
wsl --install报错“请求的名称有效,但找不到请求的数据”,通常是网络问题导致无法从微软服务器下载发行版。可以尝试手动下载 Ubuntu 22.04 的 appx 包安装,或者换一个网络环境重试。
2.4 WSL2 网络模式与端口映射的关键配置
WSL2 默认使用 NAT 网络模式,这意味着 WSL2 内部的 IP 和 Windows 主机的 IP 不在同一网段。你在 WSL2 里跑一个服务监听 8080 端口,Windows 主机上通过localhost:8080能访问,但局域网内其他机器访问不了。
如果你需要局域网访问(比如用手机测试 Hermes Agent 的接口),有两个方案。方案一是在 Windows 上做端口转发,用netsh interface portproxy命令把 Windows 的端口转发到 WSL2 的 IP。方案二是把 WSL2 的网络模式改成 mirrored,在.wslconfig文件里加networkingMode=mirrored,这样 WSL2 直接共享 Windows 的网络接口。
我一般用方案一,因为 mirrored 模式在某些 Windows 版本上还有兼容性问题。端口转发的命令示例:
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$(wsl hostname -I | awk '{print $1}')注意 WSL2 的 IP 每次重启会变,所以这个命令需要写进脚本,每次开机后重新执行。或者用 mirrored 模式一劳永逸。
2.5 WSL2 保活与 systemd 启用
WSL2 默认在最后一个终端关闭后一段时间会自动挂起,这会导致后台服务中断。解决办法是在/etc/wsl.conf里配置:
[boot] systemd=true [user] default=你的用户名然后在 Windows 的.wslconfig文件(位于用户目录下)里加:
[wsl2] vmIdleTimeout=-1vmIdleTimeout=-1表示永不超时挂起。改完执行wsl --shutdown重启 WSL2 生效。
启用 systemd 后,你就可以用systemctl管理 Hermes Agent 服务了,这是后面做服务保活的基础。
3. 云服务器方案:选型、购买与初始化配置
3.1 云服务器配置怎么选才不浪费钱
Hermes Agent 本身对资源的需求不算高,但如果你要同时跑 Docker、数据库、可能还有向量检索组件,配置就不能太低。我的建议是:
| 使用场景 | CPU | 内存 | 磁盘 | 带宽 |
|---|---|---|---|---|
| 个人测试 | 2核 | 4GB | 40GB SSD | 3Mbps |
| 小团队使用 | 4核 | 8GB | 80GB SSD | 5Mbps |
| 生产环境 | 8核 | 16GB+ | 200GB SSD | 10Mbps+ |
很多人问“云服务器32核128G中的128G指的是什么”,这里统一说一下:128G 指的是内存容量,不是磁盘。云服务器配置里的“核”是 vCPU,是虚拟核心,和物理核心有区别。对于 Hermes Agent 来说,4核8G 是性价比最高的起步配置。
关于“购买云服务器大概多少钱”,国内主流云厂商的 2核4G 配置,新用户首年通常在 100-300 元区间,4核8G 在 500-1000 元区间。具体价格波动大,建议关注各家的新用户活动。如果预算有限,也可以看看免费云服务器试用活动,但通常有时长限制。
注意:不要为了省钱选 1核2G 的配置。Docker 本身就要占几百 MB 内存,Hermes Agent 跑起来后内存占用会上去,1核2G 很容易 OOM(内存溢出)导致服务被杀。
3.2 操作系统选择与安全组配置
操作系统我推荐 Ubuntu 22.04 LTS 或 Ubuntu 24.04 LTS。如果你有国产化需求,麒麟 V10 也可以,但 Docker 安装步骤会略有不同,需要额外配置软件源。
安全组是云服务器最容易出问题的地方。Hermes Agent 默认监听的端口(假设是 8080)必须在安全组里放行,否则外网访问不了。配置方法:
- 登录云服务器控制台,找到安全组/防火墙设置。
- 添加入站规则:协议 TCP,端口 8080,来源 0.0.0.0/0(如果只自己用,可以限制为你的 IP)。
- 如果需要 SSH 管理,确保 22 端口已放行。
提示:有些云厂商默认只放行 22 和 3389,其他端口全部关闭。部署完服务发现访问不了,先检查安全组,这是最高频的排查点。
3.3 服务器初始化:用户、SSH 与基础工具
拿到服务器后,第一件事不是直接装 Docker,而是做基础初始化。我习惯做这几件事:
- 创建非 root 用户并配置 sudo 权限。直接用 root 操作风险高,误删文件后果严重。
- 配置 SSH 密钥登录,禁用密码登录。密码登录容易被暴力破解,看云服务器 TCP 连接数异常增高,往往就是被扫了。
- 更新系统软件包:
apt update && apt upgrade -y。 - 安装基础工具:
apt install -y curl wget git vim htop net-tools。
这些步骤看起来琐碎,但能避免后面很多麻烦。特别是 SSH 密钥登录,配好之后管理起来安心很多。
3.4 Docker 与 Docker Compose 安装
Hermes Agent 的部署方式以 Docker 为主,所以 Docker 环境是必须的。安装步骤:
# 卸载旧版本 apt remove -y docker docker-engine docker.io containerd runc # 安装依赖 apt install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥 mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 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/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装 Docker apt update apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 验证 docker --version docker compose version如果拉取镜像慢,可以配置镜像加速。在/etc/docker/daemon.json里加:
{ "registry-mirrors": ["https://your-mirror.example.com"] }然后systemctl daemon-reload && systemctl restart docker。镜像加速地址各云厂商都有提供,用自己服务器所在厂商的地址延迟最低。
4. Hermes Agent 服务部署与启动实操
4.1 获取部署文件与目录规划
Hermes Agent 的部署文件通常包括 Docker Compose 配置、环境变量文件、数据卷目录。我习惯把部署目录放在/opt/hermes-agent,结构如下:
/opt/hermes-agent/ ├── docker-compose.yml ├── .env ├── data/ ├── logs/ └── config/这样规划的好处是数据、日志、配置分离,备份和迁移都方便。.env文件存放敏感信息(数据库密码、API Key 等),不要提交到 Git。
4.2 环境变量配置与参数说明
.env文件是部署的核心,几个关键参数必须配对:
| 参数名 | 说明 | 示例值 |
|---|---|---|
| HERMES_PORT | 服务监听端口 | 8080 |
| HERMES_DATA_DIR | 数据目录 | /opt/hermes-agent/data |
| DB_PASSWORD | 数据库密码 | 强密码 |
| LOG_LEVEL | 日志级别 | info |
| TZ | 时区 | Asia/Shanghai |
时区这个参数容易被忽略,但不配的话日志时间戳会是 UTC,排查问题时对时间很麻烦。日志级别建议先用 info,调试阶段可以改 debug,生产环境用 warn 减少日志量。
4.3 启动服务与首次运行检查
启动命令:
cd /opt/hermes-agent docker compose up -d-d表示后台运行。启动后执行docker compose ps查看容器状态,正常应该是Up或running。如果显示Restarting或Exited,说明启动失败,需要看日志:
docker compose logs -f --tail=100首次启动通常会做一些初始化工作,比如建表、下载模型文件等,可能需要几分钟。这时候不要急着判断失败,先看日志有没有在正常输出。
4.4 状态校验:接口、端口与日志三重确认
服务起来后,怎么确认它真的正常?我一般做三重检查:
第一,端口监听检查:ss -tlnp | grep 8080,确认端口在监听。
第二,接口健康检查:curl -s http://localhost:8080/health,看返回是否正常。Hermes Agent 通常有健康检查接口,返回{"status":"ok"}之类的 JSON。
第三,日志检查:docker compose logs --tail=50,看有没有 ERROR 级别的日志。
三重都通过,基本可以确认服务正常。如果接口不通但端口在监听,可能是服务内部还在初始化,等一会儿再试。
4.5 配置 systemd 实现开机自启与保活
Docker Compose 启动的容器默认不会开机自启,服务器重启后服务就没了。解决办法是写一个 systemd 服务单元:
[Unit] Description=Hermes Agent Requires=docker.service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/hermes-agent ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down TimeoutStartSec=300 [Install] WantedBy=multi-user.target保存到/etc/systemd/system/hermes-agent.service,然后:
systemctl daemon-reload systemctl enable hermes-agent systemctl start hermes-agent这样服务器重启后 Hermes Agent 会自动拉起。TimeoutStartSec=300是给初始化留足时间,避免启动超时被 systemd 判定为失败。
5. 环境调试与常见问题排查实录
5.1 服务起不来?按这个顺序排查
服务启动失败是最常见的问题,我总结了一个排查顺序:
- 看容器状态:
docker compose ps,确认是 Exited 还是 Restarting。 - 看日志:
docker compose logs --tail=200,找 ERROR 或 Exception。 - 看端口占用:
ss -tlnp | grep 端口号,确认端口没被其他程序占用。 - 看磁盘空间:
df -h,磁盘满了会导致服务无法写入数据。 - 看内存:
free -h,内存不足会触发 OOM Killer。
这个顺序覆盖了 90% 的启动失败场景。我遇到过最隐蔽的一次是磁盘 inode 满了,df -h看空间还有,但df -i显示 inode 用尽,清理日志文件后恢复。
5.2 WSL2 环境下的典型问题
WSL2 环境下有几个高频问题:
问题一:端口在 WSL2 内能访问,Windows 主机访问不了。原因是 WSL2 的 NAT 网络模式。解决办法是配置端口转发,或者改用 mirrored 模式。
问题二:WSL2 重启后 IP 变了,之前的转发规则失效。写一个开机脚本,每次启动时重新获取 IP 并更新转发规则。
问题三:Docker 在 WSL2 里启动报错“could not safely verify the wsl2 environment”。这通常是 WSL2 版本过低或 systemd 没启用。执行wsl --update更新到最新版,并确认/etc/wsl.conf里systemd=true。
问题四:WSL2 里跑 CUDA 相关组件失败。WSL2 支持 CUDA,但需要安装 Windows 端的 NVIDIA 驱动(不是 Linux 驱动),然后在 WSL2 内安装 CUDA Toolkit。驱动版本要匹配,否则会报错。
5.3 云服务器网络与安全组问题
云服务器上最常见的问题是“服务起来了但外网访问不了”。排查步骤:
- 服务器内
curl localhost:8080是否通?通说明服务正常。 - 安全组是否放行 8080 端口?这是最高频的原因。
- 服务器防火墙(ufw/iptables)是否放行?
ufw status查看。 - 服务是否监听在 0.0.0.0 而不是 127.0.0.1?监听 127.0.0.1 的话外网访问不了。
这四个检查点按顺序过一遍,基本能定位问题。
5.4 常见问题速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 容器反复重启 | 配置错误/依赖缺失 | 看日志定位具体报错 |
| 端口不通 | 安全组/防火墙未放行 | 检查安全组和 ufw |
| 接口返回 502 | 后端服务未就绪 | 等待初始化完成或看后端日志 |
| 磁盘满 | 日志/数据未清理 | 配置日志轮转,清理旧数据 |
| 内存不足 | 配置过低 | 升级配置或限制容器内存 |
| 拉镜像超时 | 网络问题 | 配置镜像加速 |
| 时间戳不对 | 时区未配置 | 设置 TZ 环境变量 |
| 开机不自启 | 未配 systemd | 配置 systemd 服务单元 |
5.5 几个我踩过的坑和独家技巧
坑一:Docker Compose 版本不匹配。老版本的docker-compose(带横杠)和新版的docker compose(带空格)命令不通用。Ubuntu 22.04 默认源里的版本较老,建议用 Docker 官方源安装docker-compose-plugin。
坑二:数据卷权限问题。Docker 容器内以非 root 用户运行时,挂载的宿主机目录权限不对会导致写入失败。解决办法是chown -R 1000:1000 /opt/hermes-agent/data,具体 UID 看容器内用户。
坑三:日志文件无限增长。Docker 默认的 json-file 日志驱动不限制大小,跑久了日志能占满磁盘。在daemon.json里配置:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }这样每个容器最多保留 300MB 日志,自动轮转。
技巧一:用docker compose config校验配置文件。改完 compose 文件后先执行这个命令,能提前发现语法错误,避免启动时才发现。
技巧二:环境变量用docker compose config查看最终值。有时候.env文件没被正确加载,用这个命令能看到实际生效的值,排查配置问题很快。
技巧三:WSL2 里开发,Windows 上用 IDE 编辑代码。把代码放在/mnt/c/下,用 Windows 的 IDE 编辑,WSL2 里运行。但注意/mnt/c/的文件 IO 性能比 WSL2 原生文件系统差很多,如果项目大,建议代码放 WSL2 内,用 VS Code 的 Remote-WSL 插件编辑。
6. 环境调试完成后的验证与日常维护
6.1 完整验证清单
部署完成后,我建议按这个清单做一次完整验证:
- 服务进程在运行:
docker compose ps全部 Up - 端口在监听:
ss -tlnp能看到对应端口 - 健康接口正常:
curl localhost:端口/health返回正常 - 外网可访问:从另一台机器
curl 服务器IP:端口/health - 日志无 ERROR:
docker compose logs | grep -i error - 开机自启生效:
systemctl is-enabled hermes-agent返回 enabled - 数据持久化正常:重启容器后数据还在
这个清单过一遍,基本可以确认部署质量。
6.2 日常维护要点
服务跑起来只是开始,日常维护才是长期稳定的关键。我一般做这几件事:
定期看日志,不用天天看,但每周扫一眼有没有异常。配置监控告警,CPU、内存、磁盘超过阈值时通知。定期备份数据目录,特别是数据库文件。关注镜像更新,有新版本时先在测试环境验证再升级。
提示:升级前一定要备份。我见过有人直接
docker compose pull && docker compose up -d,结果新版本数据库 schema 变了,旧数据不兼容,回滚都回不去。
6.3 性能调优的几个方向
如果服务跑起来后觉得慢,可以从这几个方向调优:
数据库连接池大小,根据并发量调整。日志级别调高,减少日志写入开销。容器资源限制,给关键容器分配足够的 CPU 和内存。如果用了向量检索,索引参数和检索参数对性能影响很大,需要根据数据量调。
这些调优没有万能参数,需要根据实际负载测试。建议先用默认配置跑,遇到瓶颈再针对性调整,不要一上来就瞎调。
6.4 从本地到云端的迁移思路
本地 WSL2 调试好了,想迁到云服务器,步骤其实不复杂:
- 在云服务器上装好 Docker 环境。
- 把
/opt/hermes-agent整个目录打包传过去,或者用 Git 同步配置文件。 - 数据目录单独迁移,用
rsync或scp。 - 修改
.env里的配置(主要是 IP、端口、路径)。 - 启动服务,按验证清单检查。
注意本地和云端的路径可能不一样,.env里的路径要改。还有时区、域名这些也要根据环境调整。
我个人在实际操作中的体会是,Hermes Agent 的部署难点不在某一步特别复杂,而在于环节多、每个环节都有小坑。WSL2 的网络模式、云服务器的安全组、Docker 的日志轮转、systemd 的服务配置,这些单独看都不难,但组合起来就容易顾此失彼。我的建议是第一次部署时严格按步骤来,每步都验证通过再往下走,不要跳步。部署完成后把整个流程写成脚本或文档,下次迁移或重装时能省很多时间。另外,环境变量和敏感配置一定要和代码分离,用.env管理,这样换环境时只改配置不改代码,迁移成本最低。