Files
containers/images/hermes
grenade 745a676702
All checks were successful
images / hermes (push) Successful in 15m40s
hermes: finalize dashboard exposure + local-inference config
Confirmed against upstream: dashboard binds 0.0.0.0:9119 by default
(HERMES_DASHBOARD_HOST/PORT), so bridge + PublishPort=5100:9119 needs no
override. LLM backend uses Hermes' `custom` OpenAI-compatible provider
pointed at the local sovereign inference (hanzalova.internal:31313/v1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011D3YeWKpjg5bT488fVanCH
2026-06-23 12:22:28 +03:00
..

hermes

NousResearch Hermes Agent — a self-improving AI agent — packaged for lair infra and published to git.lair.cafe/lair/hermes.

How it's built

Upstream ships its own Dockerfile (debian 13 + s6-overlay), so there is no vendored Containerfile here. The images workflow (and build.sh) build straight from the upstream git context at the latest release tag:

podman build github.com/NousResearch/hermes-agent.git#<tag> \
  -t git.lair.cafe/lair/hermes:<version> -t git.lair.cafe/lair/hermes:latest

Builds are release-triggered (daily poll of the GitHub releases API; a build runs only when that version isn't already in our registry) and self-healing (a failed build leaves the version absent, so the next poll retries). Force a rebuild via the workflow's force dispatch input, or locally:

HERMES_REF=v0.2.0 ./build.sh

One image, two roles

Upstream's compose runs a gateway (the agent) and a dashboard (web UI on 127.0.0.1:9119) from the same image. Persistent state — config.yaml, .env, sessions, memory, skills — all lives under /opt/data (the single volume). Provider keys and the model backend go in those mounted files, never in the image.

Deploying on bob

See hermes.container — a rootful quadlet matching the existing agent-zero / open-webui services on bob. Summary:

  1. git.lair.cafe/lair/hermes:latest must be published first (run the images workflow).

  2. sudo install -d -o 10000 -g 10000 /var/lib/hermes

  3. Drop config.yaml into /var/lib/hermes (owned 10000:10000) — LLM backend → local sovereign inference. Hermes exposes a custom provider for any OpenAI-compatible endpoint, so point it at the same endpoint open-webui uses:

    # /var/lib/hermes/config.yaml
    model:
      provider: "custom"                              # OpenAI-compatible endpoint
      base_url: "http://hanzalova.internal:31313/v1"
      api_key: "beast"                                # matches open-webui's OPENAI_API_KEY
      default: "<model-id-your-endpoint-serves>"      # see: curl http://hanzalova.internal:31313/v1/models
      # context_length: 32768                         # optional
      # max_tokens:     4096                           # optional, output ceiling
    

    Any other secrets (web-search/tool keys, messaging tokens) go in /var/lib/hermes/.env, never in the quadlet.

  4. Install hermes.container to /etc/containers/systemd/, daemon-reload, start hermes.service.

Dashboard LAN exposure (resolved)

The image binds the dashboard on 0.0.0.0:9119 by default (HERMES_DASHBOARD_HOST / HERMES_DASHBOARD_PORT), so bridge networking + PublishPort=5100:9119 in the quadlet exposes it on the LAN at :5100 with no override. ⚠ The dashboard stores provider API keys and has no auth — keep it on a trusted LAN only, and front it with an authenticating reverse proxy for any wider exposure.