nix: hive-gateway v0 — nginx in front of c0re (#609)

Per mara's directive on #609: stand up a single nginx in its own
nixos-container, serve the matrix GUI static dist there, proxy
everything else to hive-c0re. v0 is HTTP-only; TLS / public-domain
shape lands in follow-ups.

New `nix/modules/hive-gateway.nix` declaring `containers.hive-gateway`
modelled on `hive-forge`:

- nixos-container running nginx, shares host netns
- `location /matrix/` → static-serves `hyperhive.matrix.gui.package`
  (fluffychat-web by default) when `matrix.gui.enable` is true
- `location /` → proxy_pass to `127.0.0.1:${dashboardPort}` with
  websocket + SSE upgrade headers + 1d read timeout

Options (`hyperhive.gateway.*`):
- `enable` (default `true`) — gateway on by default, opt out to bypass
- `port` (default `80`) — nginx listen port on the host
- `upstreamHost` / `upstreamPort` — c0re target, defaults to
  `127.0.0.1:${services.hive-c0re.dashboardPort}`
- `openFirewall` (default `true`) — open the listen port
- `localHostsEntry` (default `false`) — when true, adds an
  `/etc/hosts` entry mapping `hyperhive.domain` → `127.0.0.1` for
  local-dev / test loops without real DNS (per mara's spec)

`hive-c0re.nix` updates: when gateway is enabled, skip wiring
`HIVE_MATRIX_GUI_DIR` (gateway owns `/matrix/` now). When gateway is
off, c0re's pre-existing matrix mount stays as the fallback.

README: short "Optional" block introducing the gateway + the
`localHostsEntry` knob.

```sh
nix flake check --no-build

nix build .#docs-host
```

End-to-end eval matrix:

| gateway.enable | matrix.gui.enable | c0re HIVE_MATRIX_GUI_DIR | gateway container |
| --- | --- | --- | --- |
| true (default)  | true  | unset (gateway serves) | present |
| true            | false | unset                  | present, no /matrix |
| false           | true  | set (c0re serves)      | absent  |
| false           | false | unset                  | absent  |

- TLS termination — separate follow-up once mara picks a story
  (self-signed-mkcert vs operator-provided certs)
- Per-agent UI routing (`/agent/<name>/`) — depends on agent base-path
  support which is a frontend lift
- Subdomain routing for `matrix.${hyperhive.domain}` — same-origin
  `/matrix/` is the v0 shape per mara ("leave everything else as is")

Closes part of #609 (matrix GUI re-rooting onto nginx); leaves the
issue open for the subdomain re-root + `.well-known/matrix/client`
piece once the multi-host story matures.
This commit is contained in:
atlas 2026-05-30 10:13:26 +02:00 committed by Mara
commit b37c353f0e
3 changed files with 203 additions and 8 deletions

View file

@ -59,7 +59,7 @@ Minimal `flake.nix` for a host that runs hive-c0re:
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
hyperhive.nixosModules.default # hive-c0re + hive-forge in one import
hyperhive.nixosModules.default # hive-c0re + hive-forge + hive-gateway in one import
({ ... }: {
services.hyperhive.enable = true;
# services.hyperhive.c0re.operatorPronouns = "they/them"; # default: "she/her"
@ -78,6 +78,16 @@ manager container, and auto-rebuilds any container whose hyperhive
rev goes stale. `claude-code` is unfree — hyperhive scopes the
whitelist to itself, nothing for the operator to set.
Optional: set `services.hyperhive.gateway.enable = false;` to bypass
the default nginx in front. By default (`gateway.enable = true`) every
request hits a small nginx in its own nixos-container that proxies
to hive-c0re's dashboard on the upstream port; `/matrix/` is served
directly from `services.hyperhive.matrix.gui.package` when the matrix
GUI is on. v0 is HTTP-only (TLS lives in a follow-up); pair with
`services.hyperhive.gateway.localHostsEntry = true;` for local dev so
`http://<services.hyperhive.domain>` resolves to the host without
setting up real DNS.
Optional: set `services.hyperhive.c0re.preBuildAgentTemplates = true;`
to pre-fetch the per-container system closures into your host's
/nix/store as part of `nixos-rebuild`. First-agent-spawn then