4.4 KiB
Executable File
title, created, updated, type, namespace, tags, sources, confidence, related
| title | created | updated | type | namespace | tags | sources | confidence | related | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Hermes Deployment Patterns | 2026-05-29 | 2026-05-29 | concept | personal |
|
medium |
|
Hermes Deployment Patterns
Three distinct ways Hermes runs in the Personal OS ecosystem. Each serves a different access model and client type.
Pattern 1: Eagle Native (Mac M4)
Where: Eagle Mac M4 Max, native process (not Docker)
Transport: Zulip (Docker)
Model backend: claude-code-openai-wrapper (Python) on port 8090 — uses
claude-agent-sdk to spawn the bundled claude CLI as a subprocess and
expose an OpenAI-compatible endpoint with real streaming support.
Previous backend: openclaw-claude-proxy (Node.js) on port 3456 —
still running as fallback but streaming broken since CLI ≥ 2.1.141.
Autostart: launchd (com.openclaw.claude-proxy.plist)
Why native: Mac file system access, MCP tools (obsidian-mcp), and the cron wiki-curation job all need full host access. Docker would require volume mounts for every integration.
Key pitfall: claude-python-proxy-start.sh must source ~/.hermes/.env
explicitly — launchd does not inherit login session env. Also CLAUDE_CODE_OAUTH_TOKEN
expires (access tokens are short-lived); when it does both proxies return 401.
See claude-python-cli-proxy for full details and token-refresh procedure.
Pattern 2: Kraken Docker (RPi5)
Where: Kraken RPi5, docker compose из docker/hermes-build/
(⚠️ ранее здесь было «docker run, not compose» — это устарело, проверено 2026-09-23)
Transport: Zulip (same instance or separate)
Model backend: Gemini or OpenRouter via Hermes gateway
Autostart: restart: unless-stopped в compose
Образ: ghcr.io/mallexxx/hermes-kraken:latest (image:, без build:). uid процесса — 1000
(из USER в образе, продублирован в compose как user: "1000:1000").
Config volume: …/docker/hermes/config → /opt/data (HERMES_HOME).
⚠️ Урок (2026-09-23), переносимый на любой Docker-деплой Hermes: uid, под которым стартует
контейнер, ОБЯЗАН иметь запись в /etc/passwd. Иначе ssh/git внутри контейнера падают с
No user exists for uid <N> до чтения ключа. Записать запись изнутри нельзя (/etc/passwd
root-owned) → либо bind-mount готового passwd, либо useradd в Dockerfile, если образ
действительно собирается локально. Проверять docker inspect --format '{{.Config.Image}}' +
наличие build: в compose до правки Dockerfile. Подробности: tech/hermes-docker-kraken.
See tech/hermes-docker-kraken.
Pattern 3: Kraken API Server (OpenAI-compat)
Where: Kraken RPi5, same hermes-kraken container
Transport: HTTPS via Cloudflare Tunnel (kraken.qentra.top)
Model backend: Gemini / OpenRouter (same gateway)
Clients: Android Aide app (BYOK → Custom Endpoint), any OpenAI SDK
Why Cloudflare Tunnel: no port-forwarding on home router required.
The tunnel terminates at cloudflared running with network_mode: host,
hitting localhost:8642 directly.
Comparison
| Dimension | Eagle Native | Kraken Docker | Kraken API |
|---|---|---|---|
| Model | claude-sonnet via Python proxy (8090) | Gemini/ORouter | Gemini/ORouter |
| Transport | Zulip | Zulip | HTTPS REST |
| Clients | Cron, MCP tools | Zulip bot clients | Mobile / OpenAI SDK |
| External access | No | No | Yes (CF Tunnel) |
| MCP/tools | Full (host access) | Docker volumes | Not applicable |
| Rate limits | Claude OAuth (proxy workaround) | API keys | API keys |
Design Principle
Hermes deployments follow the client's access model:
- Interactive/tool-heavy → Eagle native (full host, MCP)
- Always-on background → Kraken Docker (low-power, 24/7)
- Mobile / external → Kraken API server (HTTPS, standard protocol)
This avoids running a single large instance with conflicting requirements. See personal-os-architecture for the full system overview.