Skip to content

Iroh relay

Fallback path for agent↔edge iroh connections when neither side has a reachable address. Optional — only deploy one if some agents or edges sit behind strict NAT.

Set TOWONEL_HUB_RELAY_URL on the hub; it advertises the URL to agents at bootstrap. Edges still take their own env:

Terminal window
-e TOWONEL_HUB_RELAY_URL=https://relay.example.eu:8443 # hub
-e TOWONEL_EDGE_RELAY_URL=https://relay.example.eu:8443 # edge

Agents pick up the hub’s URL automatically. TOWONEL_AGENT_RELAY_URL overrides it. Bad URLs warn at startup and fall back to disabled.

services:
iroh-relay:
image: docker.io/n0computer/iroh-relay:1.0.0-rc.0
network_mode: host
restart: unless-stopped
command: ["--config-path", "/etc/iroh-relay/relay.toml"]
volumes:
- ./relay.toml:/etc/iroh-relay/relay.toml:ro
- iroh-relay-data:/data
volumes:
iroh-relay-data:

relay.toml:

enable_quic_addr_discovery = true
http_bind_addr = "0.0.0.0:8080"
[tls]
hostname = "relay.example.eu"
cert_mode = "LetsEncrypt"
cert_dir = "/data/certs"
contact = "ops@example.eu"
https_bind_addr = "0.0.0.0:8443"
quic_bind_addr = "0.0.0.0:7842"
prod_tls = true

DaemonSet on hostNetwork. TLS comes from a cert-manager-issued Secret; cert_mode = "Reloading" picks up renewed certs without a restart.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: relay-example-eu
spec:
secretName: relay-example-eu-tls
dnsNames: [relay.example.eu]
issuerRef: { kind: ClusterIssuer, name: letsencrypt-production }
privateKey: { algorithm: ECDSA, size: 256, rotationPolicy: Always }
# mounted at /etc/iroh-relay/relay.toml
enable_quic_addr_discovery = true
http_bind_addr = "0.0.0.0:8080"
[tls]
hostname = "relay.example.eu"
cert_mode = "Reloading"
manual_cert_path = "/tls/tls.crt"
manual_key_path = "/tls/tls.key"
https_bind_addr = "0.0.0.0:8443"
quic_bind_addr = "0.0.0.0:7842"

Mount relay-example-eu-tls at /tls.

  • TCP 8443 — HTTPS relay traffic.
  • UDP 7842 — QUIC address discovery.