fix: forge URL + firewall for isolateContainers=true

When containers run in private netns (isolateContainers=true), host
loopback is unreachable so HIVE_FORGE_URL=http://127.0.0.1:3000 breaks.

- nix/modules/hive-network.nix: when isolateContainers is on + forge
  is enabled, open forge.httpPort on the bridge interface so agents
  can reach forgejo at bridgeIp:httpPort (forgejo binds 0.0.0.0)
- nix/modules/hive-c0re.nix: HIVE_FORGE_URL switches to bridge IP
  when network.enable && isolateContainers; loopback path retained
  when isolateContainers=false
- docs/network.md: add Forge access + Forge URL rows to effects table
- docs/gateway.md: rewrite HIVE_FORGE_URL section for both modes
This commit is contained in:
atlas 2026-06-03 16:01:23 +02:00 committed by mara
commit c97120f016
4 changed files with 38 additions and 11 deletions

View file

@ -557,12 +557,19 @@ in
HYPERHIVE_SWARM_NAME = config.services.hyperhive.swarmName;
}
// lib.optionalAttrs config.services.hyperhive.forge.enable {
# Loopback for in-cluster calls (agents share host netns;
# external `forge.<hive>` sub-domain isn't DNS-resolvable
# from inside nspawn). See
# `docs/gateway.md::HIVE_FORGE_URL: loopback for in-cluster,
# sub-domain for the operator`.
HIVE_FORGE_URL = "http://127.0.0.1:${toString config.services.hyperhive.forge.httpPort}";
# In-cluster forge URL. When containers are isolated (private netns),
# 127.0.0.1 is the container's own loopback — unreachable for host
# services. Use the bridge gateway IP instead; forgejo binds 0.0.0.0
# so it's reachable there. Shared-netns mode keeps loopback path.
# External `forge.<hive>` sub-domain isn't DNS-resolvable from inside
# nspawn either way. See `docs/gateway.md::HIVE_FORGE_URL`.
HIVE_FORGE_URL =
if
config.services.hyperhive.network.enable && config.services.hyperhive.network.isolateContainers
then
"http://${config.services.hyperhive.network.bridgeIp}:${toString config.services.hyperhive.forge.httpPort}"
else
"http://127.0.0.1:${toString config.services.hyperhive.forge.httpPort}";
}
// lib.optionalAttrs config.services.hyperhive.matrix.gui.enable {
# Availability flags read by the dashboard's `/api/state`.

View file

@ -215,6 +215,17 @@ in
ip saddr ${cfg.bridgeIp}/${toString cfg.bridgePrefixLength} ip daddr 127.0.0.0/8 drop
'';
# Allow isolated agents to reach the forge via the bridge gateway IP.
# Forgejo binds 0.0.0.0 so it's reachable at `bridgeIp:httpPort` from
# inside agent containers; without this rule the default INPUT policy
# drops the connection before it reaches forgejo. Only added when forge
# is enabled — no-op otherwise.
networking.firewall.interfaces.${cfg.bridgeName}.allowedTCPPorts =
lib.optionals config.services.hyperhive.forge.enable
[
config.services.hyperhive.forge.httpPort
];
# Tells hive-c0re to pass PRIVATE_NETWORK + bridge settings to each
# container. HIVE_NETWORK_SUBNET is host-bridge IP/prefix, not canonical
# network address — the Rust side normalises before subnet arithmetic.