Add lair/containers image-build repo; hermes as first image
Some checks failed
images / hermes (push) Has been cancelled

Builds container images for lair infra and publishes to git.lair.cafe.
Hermes Agent (NousResearch) is built directly from its upstream Dockerfile
at the latest release tag, published as git.lair.cafe/lair/hermes; the build
is release-triggered (daily API poll) and self-healing (gated on registry
presence, not a committable pin). Includes a draft rootful quadlet for bob
matching the agent-zero/open-webui convention. Convention follows gongfoo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011D3YeWKpjg5bT488fVanCH
This commit is contained in:
grenade
2026-06-23 12:17:10 +03:00
commit 214850dae4
6 changed files with 263 additions and 0 deletions

59
images/hermes/readme.md Normal file
View File

@@ -0,0 +1,59 @@
# hermes
[NousResearch Hermes Agent](https://github.com/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`](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` + `.env` into `/var/lib/hermes`:
- **LLM backend → local sovereign inference.** Point hermes at
`http://hanzalova.internal:31313/v1` (the endpoint open-webui already uses).
Hermes is OpenRouter-first with per-provider base URLs and no plain
OpenAI-base slot, so define the OpenAI-compatible provider/model in
`config.yaml` (confirm the exact schema against hermes docs).
- Secrets (any provider keys, tool keys) go in `.env`, not the quadlet.
4. Install `hermes.container` to `/etc/containers/systemd/`, `daemon-reload`,
`start hermes.service`.
### Open item: dashboard LAN exposure
The dashboard defaults to `127.0.0.1:9119` and **stores API keys with no auth**.
The draft quadlet publishes it on the LAN at `:5100` (the 5080/5090 convention),
which requires telling the dashboard to bind `0.0.0.0` inside the container (a
`config.yaml`/env setting to confirm). Only expose on a trusted LAN; front it
with an authenticating reverse proxy for anything wider.