欢迎光临
我们一直在努力

【Hermes:安装部署】11、Docker 部署 Hermes:干净隔离、数据持久化完整教程 —— 从零搭建你的专属智能体服务

在这里插入图片描述

Docker 部署 Hermes:干净隔离、数据持久化完整教程 —— 从零搭建你的专属智能体服务

不想把 Hermes 直接装在物理机上?担心依赖冲突、环境污染、升级困难?用 Docker 一键部署,干净隔离、数据持久化,还能无缝迁移。本文手把手带你完成从拉取镜像到备份恢复的全流程。

前言:为什么用 Docker 部署 Hermes?

Hermes 是 Honcho 项目的核心画像引擎,负责用户建模、记忆管理和工具调度。作为一个长期运行的服务,它需要:

  • 稳定的运行时环境(Python 版本、系统库、网络配置)
  • 持久化存储(用户画像、记忆数据、技能库)
  • 方便升级和回滚
  • 资源隔离(避免与其他应用冲突)

Docker 容器化完美解决了上述问题。更重要的是,如果你熟悉 OpenClaw 等项目的 Docker 部署经验,会发现 Hermes 的部署模式几乎完全一致——挂载配置目录 + 数据卷 + 端口映射 三板斧即可搞定。

本文将按照实际操作顺序,从拉取镜像到备份迁移,详细讲解每一个步骤,并提供常见问题的解决方案。全文包含 4 张 mermaid 流程图 和 多个代码示例,确保你即使第一次接触 Docker 也能顺利完成部署。


1. 拉取官方镜像

1.1 获取镜像

Hermes 官方镜像托管在 Docker Hub(假设地址为 honcho/hermes,实际以官方文档为准)。执行以下命令拉取最新稳定版:

docker pull honcho/hermes:latest

如果需要特定版本(如 v2.1.0):

docker pull honcho/hermes:2.1.0

1.2 验证镜像

docker images | grep hermes

输出示例:

honcho/hermes latest abc123def456 2 weeks ago 1.2GB

1.3 国内加速建议

如果拉取缓慢,可以配置 Docker 镜像加速器(如阿里云、中科大),或使用代理:

docker pull docker.mirrors.ustc.edu.cn/honcho/hermes:latest

拉取后重新打标签:

docker tag docker.mirrors.ustc.edu.cn/honcho/hermes:latest honcho/hermes:latest

#mermaid-svg-nsr8mdAngtwfH1yv{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nsr8mdAngtwfH1yv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nsr8mdAngtwfH1yv .error-icon{fill:#552222;}#mermaid-svg-nsr8mdAngtwfH1yv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nsr8mdAngtwfH1yv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nsr8mdAngtwfH1yv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nsr8mdAngtwfH1yv .marker.cross{stroke:#333333;}#mermaid-svg-nsr8mdAngtwfH1yv svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nsr8mdAngtwfH1yv p{margin:0;}#mermaid-svg-nsr8mdAngtwfH1yv .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-nsr8mdAngtwfH1yv .cluster-label text{fill:#333;}#mermaid-svg-nsr8mdAngtwfH1yv .cluster-label span{color:#333;}#mermaid-svg-nsr8mdAngtwfH1yv .cluster-label span p{background-color:transparent;}#mermaid-svg-nsr8mdAngtwfH1yv .label text,#mermaid-svg-nsr8mdAngtwfH1yv span{fill:#333;color:#333;}#mermaid-svg-nsr8mdAngtwfH1yv .node rect,#mermaid-svg-nsr8mdAngtwfH1yv .node circle,#mermaid-svg-nsr8mdAngtwfH1yv .node ellipse,#mermaid-svg-nsr8mdAngtwfH1yv .node polygon,#mermaid-svg-nsr8mdAngtwfH1yv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nsr8mdAngtwfH1yv .rough-node .label text,#mermaid-svg-nsr8mdAngtwfH1yv .node .label text,#mermaid-svg-nsr8mdAngtwfH1yv .image-shape .label,#mermaid-svg-nsr8mdAngtwfH1yv .icon-shape .label{text-anchor:middle;}#mermaid-svg-nsr8mdAngtwfH1yv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nsr8mdAngtwfH1yv .rough-node .label,#mermaid-svg-nsr8mdAngtwfH1yv .node .label,#mermaid-svg-nsr8mdAngtwfH1yv .image-shape .label,#mermaid-svg-nsr8mdAngtwfH1yv .icon-shape .label{text-align:center;}#mermaid-svg-nsr8mdAngtwfH1yv .node.clickable{cursor:pointer;}#mermaid-svg-nsr8mdAngtwfH1yv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nsr8mdAngtwfH1yv .arrowheadPath{fill:#333333;}#mermaid-svg-nsr8mdAngtwfH1yv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nsr8mdAngtwfH1yv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nsr8mdAngtwfH1yv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nsr8mdAngtwfH1yv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nsr8mdAngtwfH1yv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nsr8mdAngtwfH1yv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nsr8mdAngtwfH1yv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nsr8mdAngtwfH1yv .cluster text{fill:#333;}#mermaid-svg-nsr8mdAngtwfH1yv .cluster span{color:#333;}#mermaid-svg-nsr8mdAngtwfH1yv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nsr8mdAngtwfH1yv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nsr8mdAngtwfH1yv rect.text{fill:none;stroke-width:0;}#mermaid-svg-nsr8mdAngtwfH1yv .icon-shape,#mermaid-svg-nsr8mdAngtwfH1yv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nsr8mdAngtwfH1yv .icon-shape p,#mermaid-svg-nsr8mdAngtwfH1yv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nsr8mdAngtwfH1yv .icon-shape .label rect,#mermaid-svg-nsr8mdAngtwfH1yv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nsr8mdAngtwfH1yv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nsr8mdAngtwfH1yv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nsr8mdAngtwfH1yv :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

docker pull

Docker Hub

本地镜像存储

运行容器

挂载卷

数据持久化


2. 核心参数:-v 挂载 ~/.hermes 目录

2.1 为什么必须挂载?

Hermes 在运行过程中会产生三类重要数据:

  • 用户画像数据(六维向量、矛盾偏好表)
  • 长期记忆向量库(嵌入向量数据库)
  • 技能定义文件(用户自定义的技能)

默认情况下,这些数据存储在容器内的 /app/data 目录。如果容器被删除,所有数据都会丢失。通过挂载宿主目录,我们可以实现数据持久化。

2.2 创建宿主目录

mkdir -p ~/.hermes/data
mkdir -p ~/.hermes/config
mkdir -p ~/.hermes/logs

2.3 挂载参数详解

启动容器时需要挂载三个主要目录:

容器内路径宿主路径用途
/app/data ~/.hermes/data 画像、记忆、技能库
/app/config ~/.hermes/config 配置文件(只读)
/app/logs ~/.hermes/logs 日志文件

2.4 最小启动命令(不带配置)

docker run -d \\
–name hermes \\
-v ~/.hermes/data:/app/data \\
-v ~/.hermes/logs:/app/logs \\
-p 8080:8080 \\
honcho/hermes:latest

参数说明:

  • -d:后台运行
  • –name:容器名称,便于管理
  • -v:挂载卷(可以多次使用)
  • -p:端口映射,将宿主机的 8080 映射到容器的 8080(Hermes 默认 API 端口)

2.5 验证挂载是否成功

docker exec hermes ls -la /app/data

如果返回空目录(新建的),说明挂载正常。稍后 Hermes 会在其中创建子目录。


3. config.yaml 配置与挂载

3.1 配置文件作用

config.yaml 控制 Hermes 的核心行为,包括:

  • LLM 后端选择(OpenAI、本地模型等)
  • 数据库连接(向量数据库类型)
  • 工具启用/禁用列表
  • 日志级别、安全策略

3.2 创建配置文件

在 ~/.hermes/config/ 下创建 config.yaml(示例配置如下):

# ~/.hermes/config/config.yaml
server:
host: 0.0.0.0
port: 8080
workers: 4

llm:
provider: openai
model: gpt–4–turbo
api_key: ${OPENAI_API_KEY} # 从环境变量读取,不要明文写死

memory:
vector_db: chroma
embedding_model: text–embedding–3–small

tools:
enabled:
– web
– code_execution
– memory
disabled:
– terminal
– browser

logging:
level: info
output: /app/logs/hermes.log

3.3 挂载配置文件

修改启动命令,添加配置目录挂载(注意:配置文件需要以只读方式挂载,防止容器内意外修改):

docker run -d \\
–name hermes \\
-v ~/.hermes/data:/app/data \\
-v ~/.hermes/config:/app/config:ro \\
-v ~/.hermes/logs:/app/logs \\
-p 8080:8080 \\
-e OPENAI_API_KEY="sk-xxxx" \\
honcho/hermes:latest

ro 表示只读(read-only),防止容器内进程修改配置文件。

3.4 配置文件热加载(可选)

Hermes 支持监听配置文件变化并自动重载部分参数(如日志级别)。如果需要该功能,可以去掉 :ro,但注意安全风险。

渲染错误: Mermaid 渲染失败: Lexical error on line 8. Unrecognized text.
…p/config/config.yaml] C2[/app/da
———————–^


4. 启动、查看日志、验证运行

4.1 启动容器

使用上面准备好的完整命令启动:

docker run -d \\
–name hermes \\
–restart unless-stopped \\
-v ~/.hermes/data:/app/data \\
-v ~/.hermes/config:/app/config:ro \\
-v ~/.hermes/logs:/app/logs \\
-p 8080:8080 \\
-e OPENAI_API_KEY="your-key-here" \\
honcho/hermes:latest

–restart unless-stopped 保证容器在宿主机重启后自动启动(除非手动停止)。

4.2 查看启动日志

docker logs hermes -f

正常启动日志应包含类似:

INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8080

如果看到错误(如端口被占用、配置文件解析失败),根据提示修复。

4.3 验证运行状态

方法一:健康检查接口

curl http://localhost:8080/health

返回 {"status":"ok"} 表示服务正常。

方法二:查看进程列表

docker ps | grep hermes

状态应为 Up。

方法三:测试简单 API

curl -X POST http://localhost:8080/v1/model \\
-H "Content-Type: application/json" \\
-d '{"user_id":"test","query":"Hello"}'

如果返回合理的 JSON 响应(即使没有历史画像),说明服务正常。

4.4 常见启动问题及解决

问题现象可能原因解决方法
端口冲突 bind: address already in use 宿主 8080 端口已被占用 更换映射端口,如 -p 8081:8080
配置文件挂载失败 no such file or directory 宿主机目录不存在 创建 ~/.hermes/config 并放入 config.yaml
权限错误 Permission denied 容器内用户无权限写入挂载目录 chmod 777 ~/.hermes/data(临时)或指定用户
API 密钥无效 环境变量未正确传递 检查 -e OPENAI_API_KEY 是否有拼写错误

5. 重启、更新、删除容器

5.1 重启容器

docker restart hermes

重启后,挂载的数据不会丢失,容器会重新读取配置文件(如果修改了 config.yaml,需要重启生效,除非支持热加载)。

5.2 停止容器

docker stop hermes

5.3 更新镜像

步骤:

  • 拉取新镜像
  • 删除旧容器(注意:不删除数据卷)
  • 使用相同挂载参数启动新容器
  • # 拉取最新镜像
    docker pull honcho/hermes:latest

    # 停止并删除旧容器
    docker stop hermes
    docker rm hermes

    # 使用相同命令重新创建容器(数据目录保留)
    docker run -d –name hermes \\
    -v ~/.hermes/data:/app/data \\
    -v ~/.hermes/config:/app/config:ro \\
    -v ~/.hermes/logs:/app/logs \\
    -p 8080:8080 \\
    -e OPENAI_API_KEY="sk-xxxx" \\
    honcho/hermes:latest

    5.4 删除容器(保留数据)

    docker stop hermes
    docker rm hermes

    此时 ~/.hermes/ 目录依然存在,可以随时用相同命令重建容器。

    5.5 彻底删除(容器 + 数据)

    docker stop hermes
    docker rm hermes
    rm -rf ~/.hermes

    警告:此操作会永久删除所有用户画像、记忆和配置。

    #mermaid-svg-sVwvHxwzQEJw7EeZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sVwvHxwzQEJw7EeZ .error-icon{fill:#552222;}#mermaid-svg-sVwvHxwzQEJw7EeZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sVwvHxwzQEJw7EeZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .marker.cross{stroke:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sVwvHxwzQEJw7EeZ p{margin:0;}#mermaid-svg-sVwvHxwzQEJw7EeZ defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-sVwvHxwzQEJw7EeZ g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-sVwvHxwzQEJw7EeZ g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-sVwvHxwzQEJw7EeZ g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-sVwvHxwzQEJw7EeZ g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-sVwvHxwzQEJw7EeZ .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-sVwvHxwzQEJw7EeZ .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-sVwvHxwzQEJw7EeZ .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sVwvHxwzQEJw7EeZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sVwvHxwzQEJw7EeZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sVwvHxwzQEJw7EeZ .edgeLabel .label text{fill:#333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .label div .edgeLabel{color:#333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-sVwvHxwzQEJw7EeZ .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-sVwvHxwzQEJw7EeZ .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-sVwvHxwzQEJw7EeZ .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ #statediagram-barbEnd{fill:#333333;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .cluster-label,#mermaid-svg-sVwvHxwzQEJw7EeZ .nodeLabel{color:#131300;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .note-edge{stroke-dasharray:5;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-note text{fill:black;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram-note .nodeLabel{color:black;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagram .edgeLabel{color:red;}#mermaid-svg-sVwvHxwzQEJw7EeZ #dependencyStart,#mermaid-svg-sVwvHxwzQEJw7EeZ #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-sVwvHxwzQEJw7EeZ .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sVwvHxwzQEJw7EeZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    docker stop

    docker rm

    docker run (相同挂载)

    rm -rf ~/.hermes

    容器运行中

    停止

    删除容器

    数据保留在宿主机

    重新创建容器

    彻底删除数据


    6. 备份与迁移:打包目录即可

    6.1 备份数据

    由于所有数据都存储在 ~/.hermes 目录下,备份只需打包该目录:

    tar -czvf hermes-backup-$(date +%Y%m%d).tar.gz ~/.hermes

    6.2 恢复数据

    在新机器或重装后:

  • 安装 Docker
  • 解压备份包到 ~/.hermes
  • 拉取镜像
  • 运行相同的 docker run 命令
  • # 解压
    tar -xzvf hermes-backup-20250421.tar.gz -C ~/

    # 确保目录结构正确
    ls ~/.hermes/
    # 应看到 data/ config/ logs/

    # 启动容器(与之前完全一致)
    docker run -d –name hermes \\
    -v ~/.hermes/data:/app/data \\
    -v ~/.hermes/config:/app/config:ro \\
    -v ~/.hermes/logs:/app/logs \\
    -p 8080:8080 \\
    -e OPENAI_API_KEY="sk-xxxx" \\
    honcho/hermes:latest

    6.3 迁移到不同架构

    如果源机器是 x86_64,目标机器是 ARM64(如 Apple Silicon),需要拉取对应架构的镜像。Docker 会自动选择,但某些镜像可能没有 ARM 版本。解决方法:

    • 使用多架构镜像(官方通常提供)
    • 或在源机器上用 docker export 导出容器,再在目标机器导入(不推荐,容易出问题)

    6.4 增量备份脚本

    可以设置 cron 每天自动备份:

    #!/bin/bash
    # /usr/local/bin/backup-hermes.sh
    BACKUP_DIR="/backups/hermes"
    mkdir -p $BACKUP_DIR
    tar -czf $BACKUP_DIR/hermes-$(date +%Y%m%d-%H%M%S).tar.gz ~/.hermes
    # 保留最近7天
    find $BACKUP_DIR -name "hermes-*.tar.gz" -mtime +7 -delete

    添加 cron 任务:

    0 2 * * * /usr/local/bin/backup-hermes.sh


    7. OpenClaw 用户 Docker 经验复用

    如果你曾经部署过 OpenClaw(一个开源的爬虫框架)或其他类似服务,会发现 Hermes 的 Docker 部署模式惊人地相似。这种模式已经成为数据持久化型容器的标准实践。

    7.1 模式对比

    操作OpenClaw 示例Hermes 示例
    数据目录 -v ~/.openclaw/data:/app/data -v ~/.hermes/data:/app/data
    配置目录 -v ~/.openclaw/config:/app/config:ro -v ~/.hermes/config:/app/config:ro
    日志目录 -v ~/.openclaw/logs:/app/logs -v ~/.hermes/logs:/app/logs
    端口映射 -p 8000:8000 -p 8080:8080
    重启策略 –restart unless-stopped 相同
    备份方式 打包 ~/.openclaw 目录 打包 ~/.hermes 目录

    7.2 经验迁移清单

    如果你已经熟悉 OpenClaw 的 Docker 运维,可以快速掌握 Hermes:

  • 挂载原则:所有需要持久化的目录都映射到宿主机,配置文件只读挂载。
  • 日志管理:挂载日志目录,方便使用 logrotate 或集中日志系统。
  • 环境变量:敏感信息(API Key)通过 -e 传递,不要写在配置文件里。
  • 更新流程:pull → stop → rm → run(保留挂载卷)。
  • 备份恢复:停止容器后打包整个数据目录最安全。
  • 7.3 与 OpenClaw 共存的注意事项

    如果宿主机同时运行 OpenClaw 和 Hermes,注意:

    • 端口不冲突(OpenClaw 默认 8000,Hermes 默认 8080)
    • 数据目录分开(~/.openclaw 和 ~/.hermes)
    • 资源限制:可以使用 –cpus="1.5" –memory="2g" 限制 Hermes 容器资源占用

    docker run -d \\
    –name hermes \\
    –cpus="1.5" \\
    –memory="2g" \\
    ...其他参数...


    8. 总结:安全隔离首选方案

    8.1 回顾核心步骤

  • 拉取镜像:docker pull honcho/hermes:latest
  • 创建宿主目录:~/.hermes/{data,config,logs}
  • 编写配置:~/.hermes/config/config.yaml
  • 启动容器:挂载三个目录 + 端口映射 + 环境变量
  • 验证运行:健康检查或 API 测试
  • 日常管理:docker {stop,start,restart,logs} hermes
  • 备份迁移:打包 ~/.hermes 目录即可
  • 8.2 Docker 部署的优势总结

    优势说明
    环境隔离 不污染宿主机,依赖冲突为零
    快速部署 一条命令即可启动,无需安装 Python、数据库等
    数据持久化 通过挂载卷保证删除容器不丢数据
    易于升级/回滚 镜像版本标签管理,一键切换
    资源限制 可限制 CPU、内存,避免“吵闹邻居”问题
    跨平台一致性 开发环境(macOS)与生产环境(Linux)行为一致

    8.3 最佳实践建议

    • 永远使用 –restart unless-stopped:确保宿主机重启后服务自动恢复。
    • 配置文件中不要硬编码密钥:用环境变量 ${VAR} 然后 -e 传递。
    • 定期备份 ~/.hermes 目录:特别是生产环境,建议每天备份。
    • 监控容器日志大小:挂载的日志目录需要配合 logrotate 或容器日志驱动(如 –log-opt max-size=10m)。
    • 使用 docker-compose 管理(进阶):对于多容器应用(如 Hermes + Redis + VectorDB),建议编写 docker-compose.yml。

    8.4 示例 docker-compose.yml

    version: '3.8'
    services:
    hermes:
    image: honcho/hermes:latest
    container_name: hermes
    restart: unless–stopped
    ports:
    – "8080:8080"
    volumes:
    – ~/.hermes/data:/app/data
    – ~/.hermes/config:/app/config:ro
    – ~/.hermes/logs:/app/logs
    environment:
    – OPENAI_API_KEY=${OPENAI_API_KEY}
    logging:
    driver: "json-file"
    options:
    max-size: "10m"
    max-file: "3"

    使用 docker-compose up -d 启动。

    8.5 最终流程图:完整部署生命周期

    渲染错误: Mermaid 渲染失败: Parse error on line 3:
    …teDirs[创建 ~/.hermes/{data,config,logs}]
    ———————–^
    Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'DIAMOND_START'


    附录:常见问题 FAQ

    Q1:容器启动后马上退出,怎么办?
    A:执行 docker logs hermes 查看错误。常见原因:配置文件格式错误、端口被占用、API 密钥无效。

    Q2:如何进入容器内部调试?
    A:docker exec -it hermes /bin/bash(如果镜像有 bash)。

    Q3:挂载目录后,容器内无法写入文件?
    A:检查宿主目录权限。可以临时 chmod 777 ~/.hermes/data,或指定运行用户 –user $(id -u):$(id -g)。

    Q4:如何修改配置后不重启容器?
    A:如果 Hermes 支持热加载,发送 SIGHUP 信号:docker kill –signal=HUP hermes。否则必须重启。

    Q5:多个 Hermes 容器可以共享同一个数据目录吗?
    A:不可以。数据目录包含数据库锁文件,同时访问会损坏数据。每个容器应有独立的数据目录。

    Q6:生产环境推荐使用 Docker 吗?
    A:是的,Docker 非常适合生产环境,配合 orchestration(K8s 或 Swarm)可实现高可用。对于单机部署,Docker + 定时备份已经足够可靠。

    通过 Docker 部署 Hermes,你将获得一个干净、隔离、可迁移的智能体运行环境。无论是个人开发还是生产服务,这套方案都能让你专注于业务逻辑,而不是环境配置。

    下一步:成功运行 Hermes 后,可以尝试通过 REST API 创建第一个用户画像,或者配置 Honcho 前端应用连接到这个 Hermes 后端。

    赞(0)
    未经允许不得转载:171主机测评 » 【Hermes:安装部署】11、Docker 部署 Hermes:干净隔离、数据持久化完整教程 —— 从零搭建你的专属智能体服务
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址