第十六篇:Docker 部署 Hermes——干净又省心
Hermes Agent 官方教程第十六篇:用 Docker 容器运行 Hermes,环境隔离、开箱即用。
第十六篇:Docker 部署 Hermes——干净又省心
各位小伙伴,欢迎回来!今天咱们聊点省心的事儿——用 Docker 跑 Hermes。为啥说省心?因为镜像本身是无状态的,你的所有配置、API 密钥、会话、技能、记忆,全都存在宿主机挂载的一个目录里。想升级?拉个新镜像重新跑一下,配置一点不丢,干净利落。
首次运行:初始化配置
第一次跑 Hermes,先建个数据目录,然后交互式启动容器,跑一遍设置向导:
mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setup
向导会问你 API 密钥,然后写进 ~/.hermes/.env。这一步只需做一次。强烈建议顺手把聊天平台(Telegram、Discord 等)配好,后面网关才能干活。
小贴士:在容器里跑一次
hermes setup --portal,刷新令牌会持久化到挂载的~/.hermes卷里,之后就不用重复登录了。
网关模式:后台常驻
配置好之后,用守护模式把网关跑起来:
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
nousresearch/hermes-agent gateway run
8642 端口是网关的 OpenAI 兼容 API 服务和健康检查端点。只用聊天平台的话,这个端口可以不映射;但想要仪表盘或外部工具访问网关,就必须暴露它。
新变化:s6 自动守护
官方镜像里有个大变化——gateway run 现在由 s6-overlay 自动监管:网关进程崩了,几秒内自动重启,容器本身不会退出。docker logs 里能看到监管输出。想退出这种监管模式?加 --no-supervise 或设 HERMES_GATEWAY_NO_SUPERVISE=1,适合 CI 测试那种希望容器跟着网关一起退出的场景。生产环境建议保持默认。
开启 API 服务器
默认 API 服务器是关的。想对外暴露,需要设 API_SERVER_ENABLED=true,同时把监听地址改成 0.0.0.0,再配个至少 8 位的密钥:
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
-e API_SERVER_ENABLED=true \
-e API_SERVER_HOST=0.0.0.0 \
-e API_SERVER_KEY="$(openssl rand -hex 32)" \
-e API_SERVER_CORS_ORIGINS='*' \
nousresearch/hermes-agent gateway run
注意:给公网机器开端口有安全风险,不懂就别乱开。
仪表盘:一个容器全搞定
想要 Web 仪表盘?加个环境变量就行:
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-p 8642:8642 \
-p 9119:9119 \
-e HERMES_DASHBOARD=1 \
nousresearch/hermes-agent gateway run
仪表盘同样由 s6 监管,崩了自动拉起,日志直接进 docker logs。
挂载盘上的数据库:小心 WAL 踩坑
有个容易忽略的坑:会话存在 SQLite 数据库(/opt/data/state.db)里,默认用 WAL 日志模式。WAL 依赖共享内存,而跨虚拟机的挂载(macOS 上的 Docker Desktop、Podman、OrbStack,Windows 上的 Docker Desktop)不保证这一点,多个进程同时写可能悄悄把库写坏,主文件还照样能通过完整性检查。
Hermes 的处理方式(v2026.9.14 起):全新的库如果落在这种挂载上,会直接用回滚(DELETE)日志模式并打一条警告,你不用管;已经存在的 WAL 库不会被在线降级,而是启动时报错、hermes doctor 也会标出来。修法两种:停掉所有用到这个库的进程,用镜像自带的 Python 做一次离线转换(docker exec hermes python3 -c "import sqlite3; print(sqlite3.connect('/opt/data/state.db').execute('PRAGMA journal_mode=DELETE').fetchone()[0])"),并在 config.yaml 里设 database.journal_mode: delete;或者干脆把数据目录挪到原生卷上,比如用命名卷 -v hermes-data:/opt/data,它跑在虚拟机自己的 ext4 上,WAL 正常用。NFS、SMB、普通 FUSE 挂载检测不出来,那就手动设 database.journal_mode: delete。
无人值守网关的防呆设置
最后提醒一句:无人值守的网关和定时任务会话,现在默认就开启工具循环硬停止(通过 non_interactive_hard_stop_enabled),交互式的 CLI、TUI、桌面和 ACP 会话仍然只警告不硬停。想给某个无人值守部署关掉,在对应 profile 的 config.yaml 里写:
tool_loop_guardrails:
non_interactive_hard_stop_enabled: false
好了,Docker 部署就这些。下期见!
📖 官方文档
本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/docker