docs(gateway): document per-agent static frontend split mode
This commit is contained in:
parent
e162c1a1fa
commit
e99330ef0f
1 changed files with 73 additions and 0 deletions
|
|
@ -234,6 +234,79 @@ State lives at `/var/lib/nixos-containers/hive-forge/var/lib/forgejo/`
|
|||
and survives container restart / host reboot. To wipe, destroy the
|
||||
container.
|
||||
|
||||
## Per-agent static frontend split
|
||||
|
||||
When `services.hyperhive.frontend` is configured, hive-c0re injects
|
||||
`HIVE_AGENT_FRONTEND_DIR = "${cfg.frontend}/agent"` into its service
|
||||
environment. The nginx include generator (`gateway_nginx::write`) reads
|
||||
this variable and, when set, emits split location blocks per agent
|
||||
instead of the legacy single-proxy block.
|
||||
|
||||
**Location priority for `/agent/<name>/...`:**
|
||||
|
||||
```nginx
|
||||
# 1. Compiled assets — content-addressed nix store path, cache forever
|
||||
location ^~ /agent/<name>/static/ {
|
||||
alias <frontend>/static/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable, max-age=31536000";
|
||||
}
|
||||
|
||||
# 2. Static dist + proxy fallback for dynamic paths
|
||||
location /agent/<name>/ {
|
||||
alias <frontend>/;
|
||||
try_files $uri $uri.html $uri/index.html @<name>_dynamic;
|
||||
}
|
||||
|
||||
# 3. Proxy catchall — API, events, icon, send, login, …
|
||||
location @<name>_dynamic {
|
||||
proxy_pass <upstream>;
|
||||
proxy_set_header X-Forwarded-Prefix /agent/<name>;
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 = /__hive_agent_unreachable;
|
||||
# … (full proxy header block)
|
||||
}
|
||||
```
|
||||
|
||||
**`try_files` resolution** (nginx applies the `alias` mapping before
|
||||
checking file existence):
|
||||
|
||||
| request | resolved | outcome |
|
||||
| --- | --- | --- |
|
||||
| `/agent/iris/` | `<frontend>/index.html` | main agent page |
|
||||
| `/agent/iris/stats` | `<frontend>/stats.html` | stats page |
|
||||
| `/agent/iris/screen` | `<frontend>/screen.html` | screen page |
|
||||
| `/agent/iris/static/app.js` | caught by `^~` block first | served with immutable cache |
|
||||
| `/agent/iris/api/state` | no file match → `@iris_dynamic` | proxied to agent daemon |
|
||||
| `/agent/iris/events/live` | no file match → `@iris_dynamic` | proxied (SSE) |
|
||||
|
||||
Adding a new HTML page to the frontend dist (`dist/<page>.html`)
|
||||
automatically makes it reachable at `/agent/<name>/<page>` — no
|
||||
generator change needed.
|
||||
|
||||
**Why `^~` for `/static/`**: the `^~` prefix gives this block higher
|
||||
priority than the plain prefix `location /agent/<name>/`, so compiled
|
||||
JS/CSS assets skip `try_files` entirely and get the immutable cache
|
||||
headers. Nix store paths are content-addressed — the hash changes on
|
||||
any content change — so `max-age=31536000` is safe.
|
||||
|
||||
**Why nix store is reachable from the gateway container**: nspawn
|
||||
containers bind-mount `/nix/store` read-only by default. The
|
||||
`HIVE_AGENT_FRONTEND_DIR` path is a nix store path baked in at
|
||||
hive-c0re build time — the same path is visible to both c0re (writing
|
||||
`agents.conf`) and the gateway nginx (serving files from it).
|
||||
|
||||
**Graceful degradation**: if `HIVE_AGENT_FRONTEND_DIR` is empty or
|
||||
unset (e.g. a build that predates `cfg.frontend`), each agent gets the
|
||||
legacy single-proxy block and all traffic is forwarded to the agent
|
||||
daemon as before.
|
||||
|
||||
**`extraFiles`**: per-agent `hyperhive.frontend.extraFiles` are in
|
||||
`mergedDist`, not in the base `cfg.frontend` dist. They are not under
|
||||
the nix-store `alias` path, so requests for them fall through
|
||||
`try_files` to `@<name>_dynamic` and are served by the agent daemon
|
||||
as before.
|
||||
|
||||
## Per-agent error pages
|
||||
|
||||
`/agent/<name>/` requests hit two failure modes; both get static
|
||||
|
|
|
|||
Loading…
Reference in a new issue