stage #4491: multi-container gateway URL (#4483) + v0.51.517 CHANGELOG

This commit is contained in:
nesquena-hermes
2026-06-19 19:09:00 +00:00
parent f871131965
commit 8d56dcdbed
5 changed files with 57 additions and 4 deletions
+6
View File
@@ -3,6 +3,12 @@
## [Unreleased]
## [v0.51.517] — 2026-06-19 — Release SB (multi-container gateway URL config)
### Fixed
- **Cron jobs and gateway-backed features are reachable again in multi-container deployments (#4483).** The two- and three-container compose files now set `HERMES_API_URL=http://hermes-agent:8642` on the `hermes-webui` service, which `api/agent_health.py` consumes to locate the gateway — without it, a multi-container setup showed a spurious "gateway not configured" banner and couldn't reach cron jobs. The single-container default is unchanged (the var is unset there, falling back to local checks), and `docs/docker.md`'s stale `hermes:8642` default is corrected to `hermes-agent:8642`. Thanks @franksong2702.
## [v0.51.516] — 2026-06-19 — Release SA (stage per-session toolsets before the first message)
### Fixed
+4
View File
@@ -122,6 +122,10 @@ services:
- HERMES_WEBUI_HOST=0.0.0.0
- HERMES_WEBUI_PORT=8787
- HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui
# Let the WebUI health/status checks reach the gateway container over
# the compose network. Cron listing is local, but scheduled ticking and
# the Tasks/System gateway pill need a reachable gateway URL (#4483).
- HERMES_API_URL=http://hermes-agent:8642
# Match your host user's UID/GID for correct file permissions.
# Run `id -u` and `id -g` to find your values.
# On macOS, UIDs start at 501 (not 1000) — set these in a .env file:
+4
View File
@@ -105,6 +105,10 @@ services:
- HERMES_WEBUI_HOST=0.0.0.0
- HERMES_WEBUI_PORT=8787
- HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui
# Let the WebUI health/status checks reach the gateway container over
# the compose network. Cron listing is local, but scheduled ticking and
# the Tasks/System gateway pill need a reachable gateway URL (#4483).
- HERMES_API_URL=http://hermes-agent:8642
# Match your host user's UID/GID for correct file permissions.
# In two-container setups the WebUI auto-detects UID/GID from the shared
# hermes-home volume, but you can override explicitly if needed (#668):
+26 -4
View File
@@ -158,7 +158,12 @@ provide host kernel drivers or the NVIDIA runtime.
**Cause**: Scheduled cron ticks are not driven by the WebUI itself. The gateway daemon ticks the scheduler every 60 seconds; without one running, scheduled jobs sit idle. "Run now" / "Trigger" buttons still work because the WebUI handles those in-process.
In older gateway builds, or when the daemon runs in a separate container, `gateway_state.json` can become stale and WebUI may lose confidence even if the daemon is up. This is especially visible if only base URLs are configured (e.g. `HERMES_WEBUI_GATEWAY_BASE_URL`) and local daemon state files are not being refreshed.
The cron list itself is still read from the shared `HERMES_HOME` volume, not
from the gateway HTTP API. If the Tasks panel shows a gateway warning while the
job list loads, the warning is about scheduled ticking / gateway health, not
about the list endpoint.
In older gateway builds, or when the daemon runs in a separate container, `gateway_state.json` can become stale and WebUI may lose confidence even if the daemon is up. This is especially visible if the WebUI container has no gateway URL and can only inspect local state files from its own container.
**Fix**: Run a gateway container alongside the WebUI. The two-container compose file is the recommended path:
@@ -169,18 +174,35 @@ docker compose -f docker-compose.two-container.yml up -d
The three-container layout adds the dashboard but is otherwise the same shape. If you must stay single-container, you can run `hermes gateway` inside the container as a long-lived background process, but the compose split is sturdier.
If you maintain a custom compose file, make sure the **WebUI service** points at
the gateway service over the compose network:
```yaml
services:
hermes-webui:
environment:
- HERMES_API_URL=http://hermes-agent:8642
# HERMES_WEBUI_GATEWAY_BASE_URL=http://hermes-agent:8642 also works.
```
Do not copy only `API_SERVER_ENABLED=true` / `API_SERVER_HOST=0.0.0.0` into the
agent service as a standalone fix. If you intentionally enable the agent API
server, the agent also requires a real `API_SERVER_KEY` (at least 8 characters),
and the WebUI still needs `HERMES_API_URL` or `HERMES_WEBUI_GATEWAY_BASE_URL` to
reach that service from its container.
**Verify**: Once the gateway is up, the System Settings pill should turn green and the Tasks banner disappear. From the host:
```bash
export GATEWAY_BASE_URL="${HERMES_API_URL:-${HERMES_WEBUI_GATEWAY_BASE_URL:-http://hermes:8642}}"
export GATEWAY_BASE_URL="${HERMES_API_URL:-${HERMES_WEBUI_GATEWAY_BASE_URL:-http://hermes-agent:8642}}"
docker compose -f docker-compose.two-container.yml exec hermes-agent hermes gateway status
curl -sS "${GATEWAY_BASE_URL%/}/health/detailed" | jq '.gateway_state, .state'
```
If the service name differs in your compose file, `docker compose -f docker-compose.two-container.yml ps` lists the running services.
For container-to-container diagnostics, set one of `HERMES_API_URL` or `HERMES_WEBUI_GATEWAY_BASE_URL` in the WebUI environment when using gateway chat mode (`HERMES_WEBUI_CHAT_BACKEND=gateway`), then restart WebUI.
For container-to-container diagnostics, set one of `HERMES_API_URL` or `HERMES_WEBUI_GATEWAY_BASE_URL` in the WebUI environment, then restart WebUI.
Refs #2785.
Refs #2785, #4483.
## Three-service unified setup (v0.14+)
+17
View File
@@ -194,6 +194,23 @@ def test_compose_files_parse_as_valid_yaml():
assert "services" in data, f"{fname} must define a `services:` block"
def test_multi_container_webui_points_at_gateway_service():
"""REGRESSION (#4483): the multi-container WebUI service needs a compose
network URL for the gateway container. Cron listing reads shared state, but
scheduled ticking and the Tasks/System gateway health pill need a reachable
gateway base URL from inside the WebUI container."""
import yaml
for fname in ("docker-compose.two-container.yml", "docker-compose.three-container.yml"):
path = REPO / fname
data = yaml.safe_load(path.read_text(encoding="utf-8"))
env = data["services"]["hermes-webui"]["environment"]
assert "HERMES_API_URL=http://hermes-agent:8642" in env, (
f"{fname}: hermes-webui must point at hermes-agent over the compose "
"network so gateway health and scheduled ticking work in multi-container setups."
)
# ── 7: agent vs webui HERMES_HOME_MODE semantic asymmetry ──────────────────