飞牛NAS部署Hermes AI Agent:接入DeepSeek、微信与公网访问速查手册
我是AI时代的无业游民,我游荡在现实与意念之间
飞牛NAS部署Hermes AI Agent:接入DeepSeek、微信与公网访问速查手册

什么时候用这份手册
你有一台飞牛NAS(或任意能跑 Docker 的 x86 小主机),想在上面跑一个能接入微信、能调用 DeepSeek 这类大模型、还能从公网访问的 AI Agent,但不想从头读一遍官方文档。这份手册按"排错频率"从高到低组织,30 秒内定位到你要的那条命令或配置。前置知识只需要:会用 SSH、看得懂 YAML、知道什么是环境变量。
① 重构前的症状:为什么直接抄教程会翻车
大多数人第一次部署 Hermes 的写法是这样的——把官方 compose 文件原样复制,改个端口就 up:
# 症状版 docker-compose.yml
services:
hermes:
image: hermes-agent:latest
ports:
- "8080:8080"
environment:
- DEEPSEEK_API_KEY=sk-xxxx
- WECHAT_TOKEN=xxxx
跑起来后典型报错三连:
| 现象 | 复现方式 | 表面原因 |
|---|---|---|
| 容器启动即退出 | docker logs hermes 看到 permission denied | 数据卷属主不对 |
| 微信回调 401 | 公网访问 /wechat/callback 返回 401 | token 校验路径没对齐 |
| 公网能开页面但 Agent 无响应 | 内网正常、外网超时 | 反向代理没转发 WebSocket |
这三个症状看起来无关,其实根因是同一个:你把"能跑"当成了"配置正确"。
② 问题诊断:根因不在命令,在配置边界
- 权限问题:Hermes 容器内以非 root 用户(常见 UID 1000)写
/data,而 NAS 上挂载的目录默认属主是 root。permission denied不是镜像的错,是卷的错。 - 微信回调问题:微信公众平台的回调校验要求 URL、Token、EncodingAESKey 三者与代码侧完全一致,且必须走 80/443 端口。你映射到 8080 再套一层路径,校验就过不了。
- 公网无响应:Agent 的流式输出走 SSE/WebSocket,普通反向代理默认只转发 HTTP 短连接,长连接被掐断,表现就是"页面打开了但一直转圈"。
一句话:NAS 部署的难点从来不是"装软件",而是"把内网服务安全地暴露成一个符合第三方协议要求的端点"。
③ 重构后的写法:完整对照
关键改动 1:卷权限显式声明
services:
hermes:
image: hermes-agent:latest
user: "1000:1000" # 关键:与宿主机目录属主对齐
volumes:
- ./data:/data # 先在宿主机 chown -R 1000:1000 ./data
environment:
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} # 用 .env,别硬编码
- DEEPSEEK_BASE_URL=https://api.deepseek.com
- DEEPSEEK_MODEL=deepseek-chat
注意:
user字段和chown必须同时做,只做一样仍然会失败。
关键改动 2:微信回调走独立反代,别复用主端口
# 微信回调专用 server 块,必须 443
server {
listen 443 ssl;
server_name wx.yourdomain.com;
location /wechat/callback {
proxy_pass http://127.0.0.1:8080/wechat/callback;
proxy_set_header Host $host;
}
}
注意:微信后台填的 URL 必须与
server_name + location完全一致,多一个斜杠都会校验失败。
关键改动 3:Agent 流式接口补长连接头
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; # WebSocket 必需
proxy_buffering off; # SSE 必需
proxy_read_timeout 3600s;
}
关键改动 4:公网访问优先用隧道而非端口映射
家庭宽带多数没有固定公网 IP,直接端口映射既不稳定也不安全。更稳的做法是用 Cloudflare Tunnel 或 frp 这类内网穿透,把 443 出口交给隧道服务:
cloudflared tunnel --url http://127.0.0.1:8080
注意:隧道方案下微信回调域名要指向隧道分配的域名,且需在微信后台重新校验一次。
④ 收益与代价
| 维度 | 症状版 | 重构版 |
|---|---|---|
| 首次跑通时间 | 看似 5 分钟,排错 2 小时 | 配置 20 分钟,一次通过 |
| 微信回调成功率 | 经常 401 | 稳定 |
| 公网流式响应 | 超时/截断 | 正常 |
| 安全暴露面 | 全端口映射 | 仅隧道/443 |
| 复杂度代价 | 低 | 中(多一层反代/隧道) |
代价很明确:你多维护了一个反向代理或隧道进程,多了一个域名和证书。对于只想内网自用的场景,这部分是纯负担。
⑤ 适用边界与检查清单
不该这么改的时候:纯内网自用、不接微信、不需要公网访问——那就只需要改动 1(卷权限),其余全部省略。别为了"看起来专业"给自己加运维债。
上线前检查清单:
- 宿主机
data目录属主 = 容器user的 UID - API Key 走
.env,.env已加入.gitignore - 微信后台的 URL / Token / AESKey 与配置逐字符核对
- 反代对
/api/关闭了proxy_buffering - 公网入口只暴露 443,8080 不对公网开放
- 隧道/证书到期时间已记录
面试/作业常被追问的点:为什么 SSE 需要 proxy_buffering off?(因为缓冲会攒够一批才下发,破坏流式的"逐字返回"语义。)为什么微信回调必须 443?(平台侧校验只认标准端口。)能答上这两条,说明你是真部署过,而不是背命令。
更多推荐


所有评论(0)