服务器部署Hermes【超详细版本】(一):基础环境、Docker 镜像、目录挂载与模型配置
注服务器部署Hermes超详细指南由于过于详细所以分为三部分结尾有踩坑点说明。Hermes Agent 云服务器部署一基础环境、Docker 镜像、目录挂载与模型配置Hermes Agent 云服务器部署二微信 Weixin Gateway 与 Docker Compose 常驻运行Hermes Agent 云服务器部署三面试题库、Cron 定时任务与故障排查1. 安装基础工具最开始在服务器上执行sudoaptupdatesudoaptinstall-ygitdocker.io docker-compose-v2命令解释sudoaptupdate更新 Ubuntu 软件包索引。它不会升级软件本身只是刷新系统能看到的软件包版本列表。后续安装软件前通常都要先执行它。sudoaptinstall-ygitdocker.io docker-compose-v2安装三个工具工具作用git用于拉取 GitHub 仓库源码docker.ioUbuntu 软件源里的 Docker 引擎docker-compose-v2Docker Compose v2用于用compose.yml管理容器其中-y表示自动回答 yes避免安装过程中反复确认。2. 将当前用户加入 docker 组执行sudousermod-aGdocker$USERnewgrpdocker命令解释sudousermod-aGdocker$USER把当前用户加入docker用户组。默认情况下普通用户执行 Docker 命令可能需要加sudo例如sudodockerps加入docker组之后当前用户可以直接执行dockerps参数说明参数含义usermod修改用户信息-aG docker追加加入 docker 组$USER当前登录用户注意这里的-a很重要表示“追加”。如果没有-a可能会覆盖用户原来的组。newgrpdocker让当前 shell 立即应用新的用户组。正常情况下加入用户组后需要退出 SSH 再重新登录才生效。newgrp docker可以让当前会话立即使用新组权限。3. 拉取 Hermes Agent 源码执行gitclone https://gitclone.com/github.com/NousResearch/hermes-agent.gitcdhermes-agent命令解释gitclone https://gitclone.com/github.com/NousResearch/hermes-agent.git从 GitHub 镜像站拉取 Hermes Agent 源码。这里使用的是gitclone.com/github.com/NousResearch/hermes-agent.git而不是直接使用github.com/NousResearch/hermes-agent.git原因是国内云服务器直接访问 GitHub 可能较慢或失败使用镜像站可以提高成功率。cdhermes-agent进入刚刚 clone 下来的源码目录。4. 是否需要删除源码目录当时已经拉取了源码目录/root/hermes-agent但后续我们采用的是官方 Docker 镜像nousresearch/hermes-agent:latest因此源码目录不是必须的。不过在 Docker 镜像成功拉取之前不建议删除源码因为如果 Docker Hub 一直拉不下来还可以用源码本地构建作为备选方案。结论镜像没拉成功前先不要删除 /root/hermes-agent镜像成功拉取、setup 成功、微信网关跑通后可以删除cd/rootrm-rf/root/hermes-agent命令解释cd/root切换到 root 用户主目录。rm-rf/root/hermes-agent删除源码目录。参数说明参数含义rm删除文件或目录-r递归删除目录-f强制删除不逐个确认注意rm-rf是危险命令必须确认路径正确后再执行。删除/root/hermes-agent不会删除 Hermes 的配置、API Key、微信登录状态、cron 任务。真正要保留的是/root/.hermes5. 创建 Hermes 数据目录执行mkdir-p~/.hermeschmod700~/.hermes后来因为当前用户是 root所以实际路径是/root/.hermes命令解释mkdir-p~/.hermes创建 Hermes 的数据目录。其中~表示当前用户的 home 目录。如果当前用户是 root~ /root所以~/.hermes等价于/root/.hermes参数参数含义mkdir创建目录-p如果父目录不存在就一起创建如果目录已存在也不报错chmod700~/.hermes设置目录权限为700。权限含义数字含义7所有者可读、可写、可执行0同组用户无权限0其他用户无权限也就是说只有 root 用户自己能访问这个目录。这么做的原因是.hermes目录后续会保存API KeyHermes 配置文件微信登录状态会话数据cron 定时任务skills面试题文件所以权限应该收紧。6. 拉取 Hermes Agent Docker 镜像执行dockerpull nousresearch/hermes-agent:latest命令解释dockerpull从镜像仓库下载 Docker 镜像。nousresearch/hermes-agent:latest表示下载 NousResearch 发布的 Hermes Agent 最新镜像。镜像名拆解部分含义nousresearchDocker Hub 组织名hermes-agent镜像名latest标签表示最新版本7. Docker Hub 拉取超时问题第一次拉取时遇到类似错误failed to resolve reference docker.io/nousresearch/hermes-agent:latest failed to do request dial tcp ...:443: i/o timeout这个错误表示服务器访问 Docker Hub 超时。不是镜像名写错也不是 Hermes 项目有问题而是网络连不上 Docker Hub。8. 配置腾讯云 Docker 镜像加速因为服务器看起来是腾讯云机器所以配置腾讯云内网 Docker 镜像源mkdir-p/etc/dockercp/etc/docker/daemon.json /etc/docker/daemon.json.bak.$(date%Y%m%d%H%M%S)2/dev/null||truecat/etc/docker/daemon.jsonEOF { registry-mirrors: [ https://mirror.ccs.tencentyun.com ], dns: [ 119.29.29.29, 223.5.5.5, 8.8.8.8 ] } EOFsystemctl daemon-reload systemctl restartdocker命令解释mkdir-p/etc/docker创建 Docker 配置目录。Docker daemon 的配置文件通常在/etc/docker/daemon.json如果/etc/docker不存在这条命令会创建它。cp/etc/docker/daemon.json /etc/docker/daemon.json.bak.$(date%Y%m%d%H%M%S)2/dev/null||true备份原有 Docker 配置文件。拆解说明cp/etc/docker/daemon.json...复制原配置文件。/etc/docker/daemon.json.bak.$(date%Y%m%d%H%M%S)生成带时间戳的备份文件名。例如daemon.json.bak.20260508143025 $(date %Y%m%d%H%M%S)执行date命令并插入结果格式是年月日时分秒 2/dev/null把错误输出丢弃。如果原来的daemon.json不存在cp会报错。这里把报错隐藏掉。||true即使前面的cp失败也让整条命令返回成功。这样做是为了避免“没有旧配置文件”时中断流程。cat/etc/docker/daemon.jsonEOF ... EOF把中间的 JSON 内容写入/etc/docker/daemon.json。这是 shell heredoc 写法。写入内容为{registry-mirrors:[https://mirror.ccs.tencentyun.com],dns:[119.29.29.29,223.5.5.5,8.8.8.8]}字段解释字段作用registry-mirrorsDocker 镜像加速地址dnsDocker daemon 使用的 DNS 服务器DNS 说明DNS说明119.29.29.29腾讯 DNS223.5.5.5阿里 DNS8.8.8.8Google DNSsystemctl daemon-reload让 systemd 重新加载服务配置。虽然这里只改了 Docker 的 daemon.json但重启服务前执行一下没有坏处。systemctl restartdocker重启 Docker 服务让新的镜像源配置生效。9. 检查 Docker 镜像源是否生效执行dockerinfo|sed-n/Registry Mirrors/,10p命令解释dockerinfo查看 Docker daemon 的详细信息。sed-n/Registry Mirrors/,10p只打印包含Registry Mirrors的那一行以及后面的 10 行。如果配置成功应该能看到Registry Mirrors: https://mirror.ccs.tencentyun.com/10. 再次拉取镜像配置镜像源后再执行dockerpull nousresearch/hermes-agent:latest中间曾经出现过error from registry: unknown error但再次重试后成功Digest: sha256:634f9b15c02d4693f9c48c6763152efc0af75670de1b77d22c54e4333d730bab Status: Downloaded newer image for nousresearch/hermes-agent:latest docker.io/nousresearch/hermes-agent:latest说明Docker 拉镜像时会分层下载。即使最后一步失败前面已经下载完成的 layer 通常会保留。再次执行docker pull时会复用已下载的层不一定从头开始。所以遇到这种中途失败不要急着执行dockersystem prune因为这会清理缓存可能导致重新下载。11. 检查镜像是否完整可用执行dockerimage inspect nousresearch/hermes-agent:latest/dev/null21echoIMAGE_OK||echoIMAGE_NOT_READY命令解释dockerimage inspect nousresearch/hermes-agent:latest查看本地是否存在这个镜像以及镜像元数据是否完整。/dev/null把标准输出丢弃。21把错误输出也重定向到标准输出也就是一起丢弃。echoIMAGE_OK如果前面的docker image inspect成功就输出IMAGE_OK || echo IMAGE_NOT_READY如果前面的命令失败就输出IMAGE_NOT_READY最终用来判断镜像是否已经完整可用。12. 运行 Hermes 初始化向导镜像成功后执行dockerrun-it--rm\-v/root/.hermes:/opt/data\-eTZAsia/Shanghai\nousresearch/hermes-agent setup命令解释dockerrun创建并运行一个新的容器。-it表示交互式运行。拆开看参数含义-i保持标准输入打开-t分配一个伪终端因为 setup 是交互式向导所以必须加-it。--rm容器退出后自动删除容器本身。注意这不会删除挂载到宿主机的/root/.hermes数据。-v/root/.hermes:/opt/data挂载目录。这是非常关键的一行。含义是宿主机 /root/.hermes 映射到 容器内 /opt/data所以 Hermes 在容器里看到的/opt/data实际上就是服务器上的/root/.hermes后续所有配置、API Key、cron、微信登录状态等都会存放在这里。-eTZAsia/Shanghai设置容器环境变量TZ为上海时区。这会影响日志时间、cron 定时任务时间等。nousresearch/hermes-agent使用 Hermes Agent 镜像。setup传给 Hermes 镜像的命令表示进入初始化向导。13. Quick setup 与 Full setup初始化时出现How would you like to set up Hermes? → Quick setup — provider, model messaging (recommended) Full setup — configure everything选择Quick setup原因当前目标是尽快跑通模型调用微信聊天后续 cron 定时任务不需要一开始配置所有高级选项。Quick setup 会引导配置providermodelmessaging platform对于首次部署更合适。14. 选择模型 ProviderHermes 显示了很多 provider例如1. Nous Portal 2. OpenRouter ... 6. Xiaomi MiMo ... 15. DeepSeek ...如果使用小米模型选择6也就是Xiaomi MiMo如果使用 DeepSeek选择15也就是DeepSeek15. 小米 MiMo 模型选择问题最初考虑的模型包括mimo-v2.5-pro mimo-v2-pro mimo-v2.5 mimo-v2-omni mimo-v2-flash当时建议轻量任务优先使用mimo-v2-flash原因是当前场景主要是微信文字聊天定时提醒抽取面试题简单批改理论上不需要最强模型。但是实际运行后出现错误Provider: xiaomi Model: mimo-v2-flash Endpoint: https://token-plan-cn.xiaomimimo.com/v1 Error: HTTP 400: Not supported model mimo-v2-flash错误解释这说明当前 API Key 对应的 endpointhttps://token-plan-cn.xiaomimimo.com/v1不支持mimo-v2-flash不是 Hermes 坏了也不是 API Key 一定错了而是模型名和当前 API endpoint 或套餐不匹配。处理方式将模型从mimo-v2-flash改为更稳妥的mimo-v2-pro或者如果当前小米 Token Plan 支持mimo-v2.5-pro也可以使用它。推荐顺序对于当前微信 Agent 场景建议按这个顺序尝试mimo-v2-pro mimo-v2.5-pro mimo-v2.5 mimo-v2-omni如果mimo-v2-flash被 endpoint 明确拒绝就不要继续使用它。16. 进入终端聊天界面测试模型setup 后进入终端聊天界面Welcome to Hermes Agent! Type your message or /help for commands.输入你好如果模型配置错误会出现类似HTTP 400: Not supported model mimo-v2-flash如果模型配置正确会正常回复中文。终端聊天界面的意义终端聊天只验证Hermes Agent 能不能调用模型它不代表微信网关已经正常运行。后续微信能不能回复还要单独配置和启动 gateway。17. 退出终端聊天界面在终端聊天界面中可以输入/exit或者按Ctrl C退出聊天。注意退出终端聊天不会影响 Docker 镜像和/root/.hermes配置。但是如果你运行的是临时前台 gateway按CtrlC会停止 gateway。18. /root/.hermes 和 /opt/data 的关系后续多次遇到疑问为什么在服务器上创建 /root/.hermes/interview 却让 Hermes 读取 /opt/data/interview原因是 Docker volume 映射-v/root/.hermes:/opt/data或者在 compose 文件中volumes:-/root/.hermes:/opt/data含义是服务器宿主机路径/root/.hermes 容器内部路径 /opt/data所以宿主机路径容器内路径/root/.hermes/opt/data/root/.hermes/interview/opt/data/interview/root/.hermes/interview/questions.md/opt/data/interview/questions.md重要结论在 SSH 里编辑文件用/root/.hermes/...在 Hermes 提示词或 cron 任务里让 Agent 读取/opt/data/...19. 容器的 /opt 不是服务器的 /root曾经有一个疑问容器的 /opt 目录就是我的 /root 目录吗答案是不是只有明确挂载的这一段路径有关联/root/.hermes /opt/data容器里的/opt不是服务器的/root容器里的/opt/data才是服务器的/root/.hermes其他容器目录和宿主机没有直接关系。20. 检查实际挂载路径可以用下面命令查看容器实际挂载dockerinspect hermes--format{{range .Mounts}}{{println .Source - .Destination}}{{end}}命令解释dockerinspect hermes查看名为hermes的容器详细信息。--format{{range .Mounts}}{{println .Source - .Destination}}{{end}}只输出挂载信息。正常应该看到/root/.hermes - /opt/data这表示宿主机/root/.hermes已经挂载到容器内/opt/data。21. 在服务器上进入 Hermes 数据目录推荐直接在宿主机进入cd/root/.hermesls-la命令解释cd/root/.hermes进入 Hermes 数据目录。ls-la显示目录内容。参数说明参数含义-l以长格式显示-a显示隐藏文件因为.hermes本身是隐藏目录所以查看/root时要用ls-la/root否则普通ls/root可能看不到.hermes。22. 进入容器查看 /opt/data如果需要进入容器查看dockerexec-ithermessh进入后cd/opt/datals-la退出容器exit命令解释dockerexec-ithermessh在正在运行的hermes容器中启动一个 shell。部分含义docker exec在已运行容器里执行命令-it交互式终端hermes容器名称sh启动 shell注意容器里可能没有nano或vim所以编辑文件通常还是在宿主机/root/.hermes中完成。23. 不进入容器直接查看容器内文件可以执行dockerexec-ithermessh-lcls -la /opt/data命令解释dockerexec-ithermes进入正在运行的hermes容器执行命令。sh-lcls -la /opt/data在容器内启动 shell并执行ls-la/opt/data其中参数含义-l让 shell 以 login-like 方式处理环境-c执行后面的字符串命令24. 本阶段最终状态完成第 1 阶段后应该达到这些结果Docker 镜像已成功拉取dockerimage inspect nousresearch/hermes-agent:latest/dev/null21echoIMAGE_OK||echoIMAGE_NOT_READY输出IMAGE_OKHermes 数据目录存在ls-ld/root/.hermes可以看到目录存在。模型可以正常回复执行dockerrun-it--rm\-v/root/.hermes:/opt/data\-eTZAsia/Shanghai\nousresearch/hermes-agent chat-q你好用一句中文回复我。如果能返回中文回复说明模型/API 已经配置成功。已理解路径映射宿主机/root/.hermes 容器内/opt/data后续SSH 编辑文件用/root/.hermesHermes 读取文件用/opt/data25. 第 1 部分常用命令汇总查看 Docker 镜像dockerimages|grephermes检查 Hermes 镜像是否可用dockerimage inspect nousresearch/hermes-agent:latest/dev/null21echoIMAGE_OK||echoIMAGE_NOT_READY查看 Docker 镜像源dockerinfo|sed-n/Registry Mirrors/,10p运行 Hermes setupdockerrun-it--rm\-v/root/.hermes:/opt/data\-eTZAsia/Shanghai\nousresearch/hermes-agent setup测试模型回复dockerrun-it--rm\-v/root/.hermes:/opt/data\-eTZAsia/Shanghai\nousresearch/hermes-agent chat-q你好用一句中文回复我。查看 Hermes 数据目录ls-la/root/.hermes查看容器挂载dockerinspect hermes--format{{range .Mounts}}{{println .Source - .Destination}}{{end}}26. 本阶段易踩坑汇总坑 1Docker Hub 超时表现dial tcp ...:443: i/o timeout解决配置腾讯云 Docker 镜像源https://mirror.ccs.tencentyun.com坑 2镜像最后一步 unknown error表现error from registry: unknown error解决不要清理缓存直接重试dockerpull nousresearch/hermes-agent:latest坑 3误以为源码目录必须保留实际使用官方 Docker 镜像后源码目录可以删除。真正需要保留的是/root/.hermes坑 4mimo-v2-flash 不支持表现HTTP 400: Not supported model mimo-v2-flash解决改成mimo-v2-pro或根据套餐支持尝试mimo-v2.5-pro坑 5混淆 /root/.hermes 和 /opt/data正确理解/root/.hermes 是服务器宿主机路径 /opt/data 是容器内部路径 两者通过 Docker volume 映射到一起第 2 部分将记录Hermes Agent 云服务器部署笔记二微信 Weixin Gateway 与 Docker Compose 常驻运行会详细解释为什么终端聊天能回复不代表微信能回复gateway run是什么临时docker run和 Docker Compose 常驻运行的区别如何创建/root/compose.hermes.yml微信 pairing code 是什么为什么docker exec hermes hermes ...会失败正确批准微信配对的方法/status和/sethome的作用两个 SSH 窗口应该怎么用