Hatte nur image: hermes-agent ohne eigenen build:-Kontext, im Unterschied zum hermes-agent-Service. Compose versucht bei up erst zu pullen (Image existiert nicht auf Docker Hub), hermes-agent faengt das per build:-Fallback ab, dashboard nicht -> harter Error. Fix: gleicher build-Kontext + explizites pull_policy: build fuer beide, damit gar nicht erst gepullt wird. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Hermes Agent — Claude-Max-Proxy + Hermes selbst, alles auf einer Maschine
Repliziert den Proxy-Trick, den wir fuer ARIA nutzen: claude-max-api-proxy
(npm) wrappt die Claude Code CLI — angemeldet mit deiner Claude-Max-
Subscription — als OpenAI-kompatiblen /v1/chat/completions-Endpoint.
Hermes Agent (Nous Research,
CLI/Desktop-Agent) redet darueber mit Claude, ohne API-Kosten — laeuft ueber
die Subscription, nicht ueber Anthropic-API-Billing.
Entscheidung (Stefan): Hermes Agent selbst laeuft auf DERSELBEN Maschine
wie dieser Proxy-Stack — alles was zu Hermes gehoert auf eine Box, minimale
Latenz, nur ein Rechner zum Pflegen. ARIA bleibt komplett unangetastet
(eigenes Docker-Netz hermes-net, eigenes Claude-CLI-Login-Volume, kein
gemeinsamer Container, laeuft ja ohnehin auf einer anderen Maschine als
Hermes).
Architektur
hermes-agent (Nous Research, network_mode: host)
| HTTP, Authorization: Bearer <TOKEN>, http://localhost:8447/v1
v
hermes-gateway (Port 8447, NUR auf 127.0.0.1 gebunden)
| prueft Bearer-Token, sonst 401
v
hermes-proxy (Port 3456, NUR docker-intern im hermes-net erreichbar)
| claude-max-api-proxy -> Claude Code CLI (Claude-Max-Login)
v
Anthropic (ueber deine Claude-Max-Subscription)
hermes-agent-dashboard (127.0.0.1:9119, Hermes' eigenes Web-UI/Setup)
Warum das Gateway trotzdem noch da ist, obwohl alles auf einer Maschine
laeuft: hermes-proxy selbst hat keine Authentifizierung (genau wie ARIAs
Proxy) — jeder andere Container im selben Docker-Host koennte sonst
unbemerkt Deine Claude-Max-Subscription mitbenutzen. Das Gateway
(proxy-patches/gateway.js, pure Node, keine Extra-Deps) prueft den
Authorization: Bearer <TOKEN>-Header gegen ein Shared Secret, bevor
irgendwas an hermes-proxy weitergeleitet wird. Seit "alles auf einer
Maschine" bindet das Gateway nur noch auf 127.0.0.1, nicht mehr nach
aussen — kein anderer Rechner kommt mehr direkt ran.
Was uebernommen wurde (1:1 aus ARIAs Proxy-Setup)
- Sed-Patches an der npm-CLI-Bridge (host-binding,
--dangerously-skip-permissions, echter--system-prompt-Kanal, 24h-Timeout, Prompt via stdin) — generische Infra-Fixes, nicht ARIA-spezifisch. - Adapter-Patches (
proxy-patches/openai-to-cli.js,cli-to-openai.js) — die OpenAI-tools<-><tool_call>-Text-Bruecke. Generisch, 1:1 uebernommen. - NICHT uebernommen: ARIAs
routes.js-Patch (Live-Tool-Stream/Not-Aus fuers Diagnostic-UI, ARIA-Bridge-spezifisch). Stattdessen gibt's hier das eigenegateway.jsfuer die Auth, die ARIA in der Form nicht braucht.
Setup
-
Hermes-Agent-Sourcecode daneben klonen (das offizielle Docker-Image liegt nicht auf Docker Hub, sondern wird per
build:aus dem Repo gebaut):cd /pfad/zum/deploy-ziel git clone https://github.com/NousResearch/hermes-agent.git hermes-agent-src(dieser Clone ist in
.gitignore— bleibt lokal, wandert nicht in unser Repo) -
.envanlegen:cp .env.example .env openssl rand -hex 32 # Ausgabe in .env bei HERMES_GATEWAY_TOKEN eintragen -
Model-Config fuer Hermes seeden (einmalig, VOR dem ersten Start — danach fasst Hermes die Datei nicht mehr an):
mkdir -p hermes-data/agent-home cp hermes-agent-config/config.yaml.example hermes-data/agent-home/config.yamlDie Datei zeigt Hermes per
provider: customauf unserenhermes-gateway(http://localhost:${HERMES_GATEWAY_PORT}/v1) —${HERMES_GATEWAY_PORT}/${HERMES_GATEWAY_TOKEN}werden von Hermes selbst beim Config-Laden aus den Container-Env-Vars expandiert, die kommen aus Deiner.env. Kein manuelles Ausfuellen noetig. -
Stack starten:
docker compose up -dBaut beim ersten Mal das Hermes-Image aus
hermes-agent-src(dauert ein paar Minuten), startet dannhermes-proxy,hermes-gateway,hermes-agent(Gateway/Messaging-Prozess) undhermes-agent-dashboard. -
Einmalig Claude-CLI-Login (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription):
docker exec -it hermes-proxy claudeDanach liegen die Credentials persistent in
hermes-data/claude-config/— ueberlebt Container-Restarts. -
Testen, dass der Proxy laeuft:
curl -s http://127.0.0.1:${HERMES_GATEWAY_PORT:-8447}/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <HERMES_GATEWAY_TOKEN aus .env>" \ -d '{"model":"sonnet","messages":[{"role":"user","content":"Sag Hallo"}]}'Ohne oder mit falschem Bearer-Token gibt's
401 unauthorized. -
Mit Hermes chatten:
docker exec -it hermes-agent hermes chatoder das Dashboard per SSH-Tunnel oeffnen:
ssh -L 9119:localhost:9119 <diese-maschine>dann im Browser
http://localhost:9119.
Mobiler Client (Android)?
Zwei GRUNDVERSCHIEDENE Richtungen, nicht verwechseln:
- Unser Proxy oben (
hermes-gateway->hermes-proxy): Claude ALS Backend FUER Hermes. Kein Client redet direkt damit ausser Hermes selbst. - Hermes' EIGENER OpenAI-kompatibler API-Server (
API_SERVER_HOST/API_SERVER_KEY, auskommentiert imhermes-agent-Service): Hermes ALS Server FUER einen Chat-Client. Aktivieren +API_SERVER_KEYin.envsetzen, dann kann ein Client wie gpt_mobile oder Maid (Open Source, Android, freierbase_url+Key, kein Messenger — siehe Chat-Verlauf) sich direkt gegen Hermes verbinden. Fuer sowas wie die ARIA-App (Wake-Word, Sprachsteuerung, TTS) braeuchte man dagegen einen eigenen App-Build — kein fertiges Produkt zum Runterladen.
Sicherheitshinweis
hermes-gateway bindet jetzt nur noch auf 127.0.0.1 — von aussen kommt
niemand mehr ran, solange Du nicht selbst was aendertst (z.B. fuer den
mobilen API-Server oben, oder falls Hermes doch mal auf eine zweite Maschine
zieht). Wenn Du HERMES_GATEWAY_PORT oder API_SERVER_HOST doch mal nach
aussen exposest: der Traffic ist unverschluesseltes HTTP, kein TLS. Nicht
direkt ins offene Internet haengen — SSH-Tunnel, WireGuard/Tailscale oder
einen TLS-Reverse-Proxy davorschalten.
Verzeichnisse (nicht committet, siehe .gitignore)
hermes-agent-src/— geklonter Hermes-Agent-Sourcecode (Docker-Build-Context)hermes-data/claude-config/— Claude-CLI-Login (Browser-OAuth-Session)hermes-data/agent-home/— Hermes'~/.hermes-Aequivalent: Config (config.yaml, aushermes-agent-config/config.yaml.examplegeseedet), Sessions, Memory, Skills,.env.env— Secrets (Token, ggf. API_SERVER_KEY)
Wo deployen?
Diese Compose-Datei ist ortsunabhaengig. Stefan deployt sie selbst auf der
Ziel-Maschine (nicht aria-wohnung — komplett getrennt von ARIA). Repo klonen,
die drei Setup-Schritte oben (Hermes-Source klonen, .env, Config seeden),
dann docker compose up -d.