Repository navigation
piper v0.20.0
piper-edge: scale the relay out behind one address
piper-relay can now run as N processes behind a single public address. A new binary, piper-edge (ghcr.io/piperbox/piper-edge), is a stateless L4 entrypoint that routes every connection to the relay that owns the agent's tunnel (#521, epic #524).
What's new
piper-edge— peeks SNI on:443and Host on:80, resolves the owning relay from an in-memory copy of the pool, and splices bytes to it with a PROXY v2 header so the relay still sees the real client IP.:7000goes to the least-loaded relay;api.<apex>pins to the earliest-started relay (until #522). A relay whose dial fails is evicted (one retry on:7000only). If Postgres is unreachable the edge keeps serving from memory.- Relay pool membership — each
piper-relayheartbeats intorelay_instances(5s; live for 15s) with the addresses it advertises (PIPER_RELAY_ADVERTISE_HOST, default first non-loopback IPv4) and leaves the pool on SIGTERM. - Tunnel ownership —
agent_ownersrecords which relay terminates which agent. Register upserts, unregister clears only its own row and only when no newer session is held, and every heartbeat re-asserts ownership for held agents with no live owner. - Cluster-aware control API — a
pipercommand that lands on a relay not holding the agent is forwarded unchanged to the owner over:8080(one hop, never two).GET /agentsand the delete guard count live owners on any relay and fail closed on a lookup error. - NOTIFY-woken webhooks — parked GitHub events wake the owning relay through
piper_eventsinstead of waiting for the sweep. - Runbook: new Scale out section in
docs/runbooks/relay-deploy.mdwith a compose example (edge on the host network, relays on the bridge withPIPER_RELAY_PROXY_PROTOCOL=1).
Upgrading
- Relay schema: two new tables (
relay_instances,agent_owners) created byCREATE TABLE IF NOT EXISTSon start. Nothing existing changes; no re-enroll, no data migration. Agents and the wire protocol are untouched, so relay-before-agents ordering does not apply — old agents and this relay interoperate both ways. - Single relay, no edge: everything works as before. Two behaviour changes: SIGTERM now always drains (leaves the pool, ≤5s), and a host with no non-loopback IPv4 must set
PIPER_RELAY_ADVERTISE_HOSTor the relay refuses to start. - Behind an edge: set
PIPER_RELAY_PROXY_PROTOCOL=1on every relay,PIPER_RELAY_ADVERTISE_HOSTto an address the edge can dial, and give the edgePIPER_EDGE_DB_URL+PIPER_EDGE_APEX. Postgres must be reachable from the edge.