hermes: finalize dashboard exposure + local-inference config
All checks were successful
images / hermes (push) Successful in 15m40s
All checks were successful
images / hermes (push) Successful in 15m40s
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
This commit is contained in:
@@ -1,21 +1,21 @@
|
|||||||
# DRAFT reference quadlet for deploying Hermes on bob (bob.hanzalova.internal).
|
# Reference quadlet for deploying Hermes on bob (bob.hanzalova.internal).
|
||||||
# Deploy to /etc/containers/systemd/hermes.container (rootful, matching the
|
# Deploy to /etc/containers/systemd/hermes.container (rootful, matching the
|
||||||
# existing agent-zero.container and open-webui.container), then:
|
# existing agent-zero.container and open-webui.container), then:
|
||||||
# sudo install -d -o 10000 -g 10000 /var/lib/hermes # /opt/data owner = HERMES_UID
|
# sudo install -d -o 10000 -g 10000 /var/lib/hermes # /opt/data owner = HERMES_UID
|
||||||
# # drop config.yaml + .env into /var/lib/hermes (LLM backend, secrets) — see readme.md
|
# sudo install -o 10000 -g 10000 /path/to/config.yaml /var/lib/hermes/config.yaml
|
||||||
|
# sudo install -o 10000 -g 10000 /path/to/.env /var/lib/hermes/.env # if needed
|
||||||
# sudo systemctl daemon-reload && sudo systemctl start hermes.service
|
# sudo systemctl daemon-reload && sudo systemctl start hermes.service
|
||||||
#
|
#
|
||||||
# Once git.lair.cafe/lair/hermes:latest is published by the `images` workflow,
|
# Gated on git.lair.cafe/lair/hermes:latest being published by the `images`
|
||||||
# this is a normal pull + AutoUpdate=registry quadlet — same lifecycle as the
|
# workflow first. After that it's a normal pull + AutoUpdate=registry quadlet —
|
||||||
# other two services on bob.
|
# same lifecycle as the other two services, and now enrolled in the (enabled)
|
||||||
|
# podman-auto-update.timer.
|
||||||
#
|
#
|
||||||
# UNRESOLVED before first deploy (confirm against hermes dashboard docs):
|
# Dashboard: the image binds the dashboard on 0.0.0.0:9119 by default
|
||||||
# The dashboard binds 127.0.0.1:9119 by default. To expose it on the LAN at
|
# (HERMES_DASHBOARD_HOST / HERMES_DASHBOARD_PORT), so bridge networking +
|
||||||
# :5100 (the agent-zero=5080 / open-webui=5090 convention) the dashboard must
|
# PublishPort below exposes it on the LAN at :5100 with no override needed.
|
||||||
# be told to bind 0.0.0.0 INSIDE the container — set that in
|
# ⚠ The dashboard stores provider API keys and has NO auth — keep it on a trusted
|
||||||
# /var/lib/hermes/config.yaml (or a hermes dashboard-host env) and keep the
|
# LAN only; front it with an authenticating reverse proxy for anything wider.
|
||||||
# PublishPort below. ⚠ It stores provider API keys and has no auth, so only
|
|
||||||
# expose on a trusted LAN — consider a reverse proxy with auth for anything wider.
|
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Hermes Agent
|
Description=Hermes Agent
|
||||||
@@ -26,20 +26,15 @@ Wants=network-online.target
|
|||||||
Image=git.lair.cafe/lair/hermes:latest
|
Image=git.lair.cafe/lair/hermes:latest
|
||||||
ContainerName=hermes
|
ContainerName=hermes
|
||||||
AutoUpdate=registry
|
AutoUpdate=registry
|
||||||
# Bridge + PublishPort keeps the 50X0 LAN convention. Requires the dashboard to
|
# Keeps the 50X0 LAN convention (agent-zero=5080, open-webui=5090, hermes=5100).
|
||||||
# bind 0.0.0.0:9119 inside the container (see note above). If you instead accept
|
|
||||||
# host networking like upstream's compose, replace the next two lines with
|
|
||||||
# `Network=host` and configure the dashboard bind/port directly.
|
|
||||||
PublishPort=5100:9119
|
PublishPort=5100:9119
|
||||||
Volume=/var/lib/hermes:/opt/data:Z
|
Volume=/var/lib/hermes:/opt/data:Z
|
||||||
# Upstream drops to the non-root hermes user (uid/gid 10000); /var/lib/hermes
|
# Upstream drops to the non-root hermes user (uid/gid 10000); /var/lib/hermes
|
||||||
# must be owned by 10000:10000 on the host (see install -d above).
|
# must be owned 10000:10000 on the host (see install -d above).
|
||||||
Environment=HERMES_UID=10000
|
Environment=HERMES_UID=10000
|
||||||
Environment=HERMES_GID=10000
|
Environment=HERMES_GID=10000
|
||||||
# LLM backend: point hermes at the local sovereign inference at
|
# LLM backend (local sovereign inference) is configured in
|
||||||
# http://hanzalova.internal:31313/v1 (same endpoint open-webui uses). Hermes is
|
# /var/lib/hermes/config.yaml via provider: "custom" -> see readme.md.
|
||||||
# OpenRouter-first with per-provider base URLs and no plain OpenAI slot, so the
|
|
||||||
# model routing is configured in /var/lib/hermes/config.yaml, not here. See readme.md.
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
@@ -40,20 +40,31 @@ existing `agent-zero` / `open-webui` services on bob. Summary:
|
|||||||
1. `git.lair.cafe/lair/hermes:latest` must be published first (run the `images`
|
1. `git.lair.cafe/lair/hermes:latest` must be published first (run the `images`
|
||||||
workflow).
|
workflow).
|
||||||
2. `sudo install -d -o 10000 -g 10000 /var/lib/hermes`
|
2. `sudo install -d -o 10000 -g 10000 /var/lib/hermes`
|
||||||
3. Drop `config.yaml` + `.env` into `/var/lib/hermes`:
|
3. Drop `config.yaml` into `/var/lib/hermes` (owned `10000:10000`) — **LLM backend
|
||||||
- **LLM backend → local sovereign inference.** Point hermes at
|
→ local sovereign inference.** Hermes exposes a `custom` provider for any
|
||||||
`http://hanzalova.internal:31313/v1` (the endpoint open-webui already uses).
|
OpenAI-compatible endpoint, so point it at the same endpoint open-webui uses:
|
||||||
Hermes is OpenRouter-first with per-provider base URLs and no plain
|
|
||||||
OpenAI-base slot, so define the OpenAI-compatible provider/model in
|
```yaml
|
||||||
`config.yaml` (confirm the exact schema against hermes docs).
|
# /var/lib/hermes/config.yaml
|
||||||
- Secrets (any provider keys, tool keys) go in `.env`, not the quadlet.
|
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`,
|
4. Install `hermes.container` to `/etc/containers/systemd/`, `daemon-reload`,
|
||||||
`start hermes.service`.
|
`start hermes.service`.
|
||||||
|
|
||||||
### Open item: dashboard LAN exposure
|
### Dashboard LAN exposure (resolved)
|
||||||
|
|
||||||
The dashboard defaults to `127.0.0.1:9119` and **stores API keys with no auth**.
|
The image binds the dashboard on **`0.0.0.0:9119` by default**
|
||||||
The draft quadlet publishes it on the LAN at `:5100` (the 5080/5090 convention),
|
(`HERMES_DASHBOARD_HOST` / `HERMES_DASHBOARD_PORT`), so bridge networking +
|
||||||
which requires telling the dashboard to bind `0.0.0.0` inside the container (a
|
`PublishPort=5100:9119` in the quadlet exposes it on the LAN at `:5100` with no
|
||||||
`config.yaml`/env setting to confirm). Only expose on a trusted LAN; front it
|
override. ⚠ The dashboard **stores provider API keys and has no auth** — keep it
|
||||||
with an authenticating reverse proxy for anything wider.
|
on a trusted LAN only, and front it with an authenticating reverse proxy for any
|
||||||
|
wider exposure.
|
||||||
|
|||||||
Reference in New Issue
Block a user