Files
netbird/infrastructure_files/docker-compose.yml.tmpl
Claude e3c23c263b relay: deploy templates expose UDP, mgmt threads transport hints
Two follow-ups to the WebTransport/ALPN-mux landing:

Deployment templates publish UDP alongside TCP for the relay so the
single ALPN-multiplexed socket can serve raw QUIC and WebTransport
clients on the same port as the existing WebSocket transport.

- docker-compose.yml.tmpl: adds the matching `/udp` mapping; the relay
  was already binding both stacks, the host port just wasn't published.
- docker-compose.yml.tmpl.traefik: WebTransport is the awkward case —
  Traefik can't proxy WT sessions, so the relay container now publishes
  UDP/443 directly and obtains its own Let's Encrypt cert (separate
  volume), while the TCP /relay route stays behind Traefik unchanged so
  WS-only clients keep working.

Management server learned to advertise per-relay transport hints:

- Config gains an optional `Endpoints []{URL, Transports}` block on the
  Relay section, mirrored to clients as RelayConfig.endpoints.
- `Addresses` is still emitted as RelayConfig.urls so older agents keep
  working unchanged.
- A single BuildRelayConfigProto helper is the only place that builds
  the proto, called from both toNetbirdConfig and the token push paths.

The GeoDNS case is operator-asserted, not probed: a single URL fans out
to several physical relays, and the Transports list must already be the
intersection of what every backend supports. Documented on the config
struct — if any backend behind a hostname can't speak h3, the operator
drops "wt" from that hostname's list and no client tries it there.
2026-05-17 11:21:38 +00:00

128 lines
4.3 KiB
Cheetah

x-default: &default
restart: 'unless-stopped'
logging:
driver: 'json-file'
options:
max-size: '500m'
max-file: '2'
services:
# UI dashboard
dashboard:
<<: *default
image: netbirdio/dashboard:$NETBIRD_DASHBOARD_TAG
ports:
- 80:80
- 443:443
environment:
# Endpoints
- NETBIRD_MGMT_API_ENDPOINT=$NETBIRD_MGMT_API_ENDPOINT
- NETBIRD_MGMT_GRPC_API_ENDPOINT=$NETBIRD_MGMT_API_ENDPOINT
# OIDC
- AUTH_AUDIENCE=$NETBIRD_DASH_AUTH_AUDIENCE
- AUTH_CLIENT_ID=$NETBIRD_AUTH_CLIENT_ID
- AUTH_CLIENT_SECRET=$NETBIRD_AUTH_CLIENT_SECRET
- AUTH_AUTHORITY=$NETBIRD_AUTH_AUTHORITY
- USE_AUTH0=$NETBIRD_USE_AUTH0
- AUTH_SUPPORTED_SCOPES=$NETBIRD_AUTH_SUPPORTED_SCOPES
- AUTH_REDIRECT_URI=$NETBIRD_AUTH_REDIRECT_URI
- AUTH_SILENT_REDIRECT_URI=$NETBIRD_AUTH_SILENT_REDIRECT_URI
- NETBIRD_TOKEN_SOURCE=$NETBIRD_TOKEN_SOURCE
# SSL
- NGINX_SSL_PORT=443
# Letsencrypt
- LETSENCRYPT_DOMAIN=$NETBIRD_LETSENCRYPT_DOMAIN
- LETSENCRYPT_EMAIL=$NETBIRD_LETSENCRYPT_EMAIL
volumes:
- $LETSENCRYPT_VOLUMENAME:/etc/letsencrypt/
# Signal
signal:
<<: *default
image: netbirdio/signal:$NETBIRD_SIGNAL_TAG
depends_on:
- dashboard
volumes:
- $SIGNAL_VOLUMENAME:/var/lib/netbird
- $LETSENCRYPT_VOLUMENAME:/etc/letsencrypt:ro
ports:
- $NETBIRD_SIGNAL_PORT:80
# # port and command for Let's Encrypt validation
# - 443:443
# command: ["--letsencrypt-domain", "$NETBIRD_LETSENCRYPT_DOMAIN", "--log-file", "console"]
command: [
"--cert-file", "$NETBIRD_MGMT_API_CERT_FILE",
"--cert-key", "$NETBIRD_MGMT_API_CERT_KEY_FILE",
"--log-file", "console",
"--port", "80"
]
# Relay
#
# The relay listens on the same address for three transports, multiplexed by
# ALPN on a single TLS endpoint:
# - TCP: WebSocket (rels:// path /relay) — universal, works through any HTTP proxy
# - UDP: raw QUIC (nb-quic ALPN) — used by native clients
# - UDP: HTTP/3 + WebTransport (h3 ALPN, path /relay) — used by browser/WASM clients
# Both TCP and UDP must be published on the same port. Operators who want to
# disable a transport for clients should NOT remove the port mapping — the
# listener still binds — instead drop the transport from each entry's
# `transports:` list in management.json so the management server stops
# advertising it.
relay:
<<: *default
image: netbirdio/relay:$NETBIRD_RELAY_TAG
environment:
- NB_LOG_LEVEL=info
- NB_LISTEN_ADDRESS=:$NETBIRD_RELAY_PORT
- NB_EXPOSED_ADDRESS=$NETBIRD_RELAY_ENDPOINT
# todo: change to a secure secret
- NB_AUTH_SECRET=$NETBIRD_RELAY_AUTH_SECRET
ports:
- $NETBIRD_RELAY_PORT:$NETBIRD_RELAY_PORT
- $NETBIRD_RELAY_PORT:$NETBIRD_RELAY_PORT/udp
# Management
management:
<<: *default
image: netbirdio/management:$NETBIRD_MANAGEMENT_TAG
depends_on:
- dashboard
volumes:
- $MGMT_VOLUMENAME:/var/lib/netbird
- $LETSENCRYPT_VOLUMENAME:/etc/letsencrypt:ro
- ./management.json:/etc/netbird/management.json
ports:
- $NETBIRD_MGMT_API_PORT:443 #API port
# # command for Let's Encrypt validation without dashboard container
# command: ["--letsencrypt-domain", "$NETBIRD_LETSENCRYPT_DOMAIN", "--log-file", "console"]
command: [
"--port", "443",
"--log-file", "console",
"--log-level", "info",
"--disable-anonymous-metrics=$NETBIRD_DISABLE_ANONYMOUS_METRICS",
"--single-account-mode-domain=$NETBIRD_MGMT_SINGLE_ACCOUNT_MODE_DOMAIN",
"--dns-domain=$NETBIRD_MGMT_DNS_DOMAIN"
]
environment:
- NETBIRD_STORE_ENGINE_POSTGRES_DSN=$NETBIRD_STORE_ENGINE_POSTGRES_DSN
- NETBIRD_STORE_ENGINE_MYSQL_DSN=$NETBIRD_STORE_ENGINE_MYSQL_DSN
# Coturn
coturn:
<<: *default
image: coturn/coturn:$COTURN_TAG
#domainname: $TURN_DOMAIN # only needed when TLS is enabled
volumes:
- ./turnserver.conf:/etc/turnserver.conf:ro
# - ./privkey.pem:/etc/coturn/private/privkey.pem:ro
# - ./cert.pem:/etc/coturn/certs/cert.pem:ro
network_mode: host
command:
- -c /etc/turnserver.conf
volumes:
$MGMT_VOLUMENAME:
$SIGNAL_VOLUMENAME:
$LETSENCRYPT_VOLUMENAME: