Repository navigation
chore: 自行維護 Hermes Docker 映像檔(官方 PR #1523 移除後) #2
Description
背景
openab PR #1523 移除了官方 Hermes agent 的預建置映像檔支援(Dockerfile.hermes、CI workflow、bake target 等,共 20 檔 −441 行)。官方不再發佈新的 Hermes 映像檔標籤。
官方提供的自行建置指南:https://eli5.openab.dev/howto-build-hermes-openab-image/
核心做法:從 v0.10.0-beta.3 tag 取回 Dockerfile.hermes,自行建置並發佈到自己的 GHCR。
為什麼移除
- Hermes 的安裝腳本從
raw.githubusercontent.com抓取,在共用 CI runner 上頻繁回傳 429(rate limit),導致 Docker Smoke Test 失敗 - 先前加上的重試強化只是遮掩問題
- 使用率相對維護成本偏低
Hermes 映像檔為什麼這麼大
分析 Dockerfile.hermes(v0.10.0-beta.3)和 Hermes 安裝腳本(install.sh)後,映像檔的膨脹來自以下多層堆疊:
1. 基礎映像:python:3.12-slim-trixie(~150MB 壓縮)
runtime stage 使用 Debian slim,已經是相對精簡的選擇。
2. 系統套件(apt-get install)
ca-certificates curl procps ripgrep tini git ffmpeg unzip xz-utils
ffmpeg是最大的單一套件,安裝後約 100–200MB,僅用於 TTS 語音訊息功能git也不小(~30MB),但 Hermes 的 skill 同步功能需要它
3. Hermes Agent 本體(install.sh 安裝)
安裝腳本執行以下動作:
- 安裝 uv(Rust-based Python 套件管理器)
git clone整個 hermes-agent repo 到/usr/local/lib/hermes-agent- 建立 Python venv
uv sync --extra all --locked安裝完整依賴樹
核心依賴(pyproject.toml dependencies)——每個 session 都用到的:
| 套件 | 用途 | 大小影響 |
|---|---|---|
fastapi + uvicorn[standard] |
Dashboard/API 伺服器 | 中(含 starlette, uvloop, httptools) |
openai |
LLM provider SDK | 中 |
pydantic |
資料驗證 | 大(含 pydantic-core Rust 擴充) |
Pillow |
圖片縮放(vision tools) | 大(~30MB) |
httpx[socks] |
HTTP client | 中 |
rich |
終端格式化 | 小 |
websockets |
CDP browser 控制 | 小 |
PyJWT[crypto] |
Skills Hub JWT 認證 | 中(含 cryptography) |
python-multipart |
檔案上傳 | 小 |
psutil |
程序管理 | 小 |
| 其餘十幾個... | 各種功能 | 累計顯著 |
[all] extra 額外帶入的:
google-api-python-client+ 相關套件(Google Workspace skill)mcp+starlette(MCP server)agent-client-protocol(ACP adapter)youtube-transcript-apiwebextra(fastapi dashboard 完整版)
注意:Hermes 用的是 FastAPI,不是 Flask。 FastAPI 的依賴鏈(starlette + pydantic + uvicorn + uvloop + httptools)同樣不輕量。
4. Node.js runtime(~80–100MB)
安裝腳本會裝 Node.js 22 LTS,用於 browser tools(agent-browser)。在 Docker 映像檔裡這是完整的 Node 二進位 + npm。
5. gh CLI(~30–40MB)
Dockerfile 額外安裝 GitHub CLI,用於 agent 操作 GitHub 的場景。
6. openab Rust binary(~10–20MB)
從 builder stage(rust:1-bookworm)編譯後 COPY 過來,這部分反而是最小的。
估計總映像檔大小
| 層 | 估計大小 |
|---|---|
| python:3.12-slim-trixie base | ~150MB |
| apt-get 套件(含 ffmpeg) | ~200MB |
| Hermes agent + Python 依賴([all]) | ~400–600MB |
| Node.js 22 LTS | ~80MB |
| gh CLI | ~35MB |
| openab binary | ~15MB |
| 總計(壓縮前) | ~900MB – 1.1GB |
瘦身方向(未來可探索)
- 移除 ffmpeg:如果不需要 TTS 語音功能,這一項就省 100–200MB
- 不裝
[all]extra:只裝核心dependencies,不要 Google/MCP/YouTube 等 extras,按需 lazy-install - 不裝 Node.js:如果不需要 browser tools
- 不裝 gh CLI:如果 agent 不需要操作 GitHub
- 用 multi-stage 更積極:Python 依賴裝完後清除 pip/uv cache、
.git目錄、__pycache__ - 考慮 Alpine base:但 Python wheel 相容性會變差
自行建置的步驟摘要
來源:https://eli5.openab.dev/howto-build-hermes-openab-image/
# 1. 取得 Dockerfile
curl -fsSL https://raw.githubusercontent.com/openabdev/openab/v0.10.0-beta.3/Dockerfile.hermes -o Dockerfile.hermes
# 2. Clone 原始碼(建置 openab 需要)
git clone --depth 1 --branch v0.10.0-beta.3 https://github.com/openabdev/openab.git openab-src
cd openab-src
# 3. 建置
docker build -f ../Dockerfile.hermes -t ghcr.io/<你>/openab-hermes:v0.10.0-beta.3 .
# 4. 推送到 GHCR
docker push ghcr.io/<你>/openab-hermes:v0.10.0-beta.3也可以用 GitHub Actions 自動化(詳見指南 Chapter 5)。
TODO
- 確認是否需要自行維護 Hermes 映像檔
- 如果需要,建立 GitHub Actions workflow 自動建置
- 評估映像檔瘦身的優先項目(ffmpeg? Node.js? extras?)
- 測試建置後的映像檔是否正常運作
補充分析:ffmpeg、Node.js/Bun、官方瘦身計畫
ffmpeg 為什麼需要?能不能拿掉?
用途:TTS(文字轉語音)音訊格式轉換。
Hermes 支援多個 TTS provider(edge-tts、ElevenLabs、OpenAI、MiniMax、Mistral Voxtral),回傳的音訊格式各異(mp3, opus, wav, ogg 等),ffmpeg 負責統一轉碼。
結論:如果不用語音功能,可以完全不裝 ffmpeg,省 ~150MB。 TTS 本身是 optional extra(edge-tts 不在核心 dependencies 裡),安裝腳本中 ffmpeg 安裝也不是強制的。
Node.js 能否換成 Bun?
Node.js 在 Hermes 裡有三個用途:
| 用途 | 說明 | 能換 Bun? |
|---|---|---|
agent-browser |
瀏覽器自動化工具 | 可能 |
| Dashboard SPA | React/Vite 前端(npm workspace web) |
可能 |
| Desktop app | Electron 桌面版 | 不行(Electron 綁 Node) |
有趣發現: Hermes issue #93760 揭露 .bun/install cache 在 HERMES_HOME 下佔了 2.5GB(佔 backup 的 82%),代表 agent 子程序已經在透過 Bun 裝套件。
但在 Docker 裡換 Bun 有障礙: monorepo 用 npm workspaces、Desktop 依賴 Electron(硬綁 Node)、agent-browser 相容性未驗證。
更好的做法:如果只需要 ACP adapter(hermes-acp)跑在 openab 裡、不需要 dashboard 和 desktop,可以完全不裝 Node.js。 hermes-acp 是純 Python 入口(acp_adapter.entry:main)。
Hermes 官方有瘦身計畫嗎?
沒有找到任何明確的 Docker image 瘦身 issue 或 roadmap。
但 pyproject.toml 裡有 2026-05-12 的 policy change(Mini Shai-Hulud 供應鏈攻擊事件後):把所有可選後端從 [all] extra 移除,改用 tools/lazy_deps.py 按需安裝。這是 Python 依賴層面的精簡,不是 Docker image 層面。
建議方向:Sidecar 架構
與其打包一個全家桶映像檔,可以拆成最小核心 + sidecar 外掛:
核心容器(~250MB 目標):
python:3.12-slimbase- openab Rust binary
hermes-acp(純 Python ACP adapter)- Hermes 核心依賴(
dependencies不含[all]extra) - 不裝:ffmpeg、Node.js、gh CLI
Sidecar 容器(按需掛載):
- TTS sidecar:ffmpeg + edge-tts/elevenlabs
- Browser sidecar:Node.js + agent-browser
- Dashboard sidecar:Node.js + React SPA
- GitHub sidecar:gh CLI(或直接用 API)
這樣核心映像檔可以從 ~1GB 縮到 ~250MB,需要的功能再用 sidecar 加進去。
Activity
howie commentedon Sep 12, 2026
429 修復方案已實作
分支:
worktree-fix-hermes-dockerfile(diff)根因
Dockerfile.hermes第 34 行curl -fsSL raw.githubusercontent.com/...從 GitHub 的 raw file endpoint 抓 install.sh,該端點 unauthenticated rate limit 極低(~60 req/hr/IP),共用 CI runner 的 IP 被多個 org 共用,頻繁 429。修法
完全繞過
raw.githubusercontent.com,改用三段式 multi-stage build:git clone(走 Git smart HTTP,不同 rate limit pool)+uv syncghcr.io/astral-sh/uv:latestCOPY(官方 container image,走 GHCR CDN)額外改進
HERMES_PROFILEbuild arg:minimal(~250MB)/full(~900MB)tools/lazy_deps.py按需安裝.git/ uv cache / pip / setuptools 縮小映像