Skip to content

LiveKit configuration

This content is for the 1.0 version. Switch to the latest version for up-to-date documentation.

StreamHub doesn’t fork or patch LiveKit — it drives a stock livekit-server through its official SDK and webhooks, and ships the config for it. There are two ways that config gets to LiveKit, matching the two deploy shapes.

In docker-compose.yml, LiveKit runs as the livekit service (livekit/livekit-server:v1.8.4), on network_mode: host, depending on redis.

Compose substitutes ${LIVEKIT_*} values from your .env into the block:

docker-compose.yml (livekit service, environment.LIVEKIT_CONFIG)
port: 7880
bind_addresses: [""]
rtc:
tcp_port: 7881
udp_port: 7882
use_external_ip: true
redis:
address: ${LIVEKIT_REDIS_ADDRESS:-127.0.0.1:6379}
password: ${LIVEKIT_REDIS_PASSWORD:-}
keys:
${LIVEKIT_API_KEY}: ${LIVEKIT_API_SECRET}
webhook:
api_key: ${LIVEKIT_API_KEY}
urls:
- ${LIVEKIT_WEBHOOK_URL:-http://127.0.0.1:3020/api/v1/webhooks/livekit}
turn:
enabled: false
logging:
level: info
prometheus_port: 6789
Key Purpose
port: 7880 Signaling/API port, proxied at /rtc by Caddy/nginx.
rtc.tcp_port: 7881 WebRTC TCP fallback (ICE/TCP) — not proxied, reached directly.
rtc.udp_port: 7882 The single UDP mux port for all WebRTC media — not proxied, reached directly.
rtc.use_external_ip: true Autodetects the server’s public IP via STUN, since LiveKit doesn’t sit behind an L4 load balancer here.
redis.address / password Coordination redis. Single-node: local. Edge nodes point this at the origin’s redis (set by install.sh --join) — this is what gives WebRTC session affinity across a cluster.
keys The LIVEKIT_API_KEY/LIVEKIT_API_SECRET pair core uses to mint tokens and drive the SDK. Must be identical across every node of a cluster.
webhook Points room/egress/ingress events back at core’s /api/v1/webhooks/livekit. An edge node’s LIVEKIT_WEBHOOK_URL is set to the origin’s core — no core runs on an edge.
turn.enabled: false Embedded TURN is off by default; enable it once you have a domain + cert (TURN/TLS on 3478/udp).
prometheus_port: 6789 Native LiveKit Prometheus metrics, on the host network. Scrape 127.0.0.1:6789 locally — do not open 6789 on the firewall.

Native systemd alternative (deploy/livekit.yaml)

Section titled “Native systemd alternative (deploy/livekit.yaml)”

For the systemd + nginx plain-server deploy shape (no Docker for the SFU itself), deploy/livekit.yaml is the config template:

deploy/livekit.yaml
port: 7880
bind_addresses:
- ""
rtc:
tcp_port: 7881
udp_port: 7882 # single UDP mux port — open on the firewall
use_external_ip: true # autodetects the public IP via STUN
redis:
address: localhost:6379
keys:
<API_KEY>: <API_SECRET>
turn:
enabled: false # enable once you have a domain + cert (TURN/TLS on 5349)
logging:
level: info
json: false

Deploy it by hand:

Terminal window
livekit-server generate-keys # → API_KEY / API_SECRET
# copy deploy/livekit.yaml → /etc/livekit/livekit.yaml, chmod 600, owner root
# fill in <API_KEY>/<API_SECRET> with the generated pair
# copy deploy/livekit.service → /etc/systemd/system/livekit.service
systemctl enable --now livekit

The same <API_KEY>/<API_SECRET> pair must also be set as LIVEKIT_API_KEY/ LIVEKIT_API_SECRET in core’s environment, so tokens core mints validate against this server.

  • 7880/tcp (signaling) is proxied at /rtc by the reverse proxy — clients connect over wss.
  • 7881/tcp (TCP fallback) and 7882/udp (media) are not proxied; they must be reachable on the server’s public IP directly.
  • use_external_ip: true means LiveKit itself resolves the address it advertises to clients via STUN — there’s no separate “public IP” setting to configure.

See Requirements for the full port/firewall table, and Join a cluster for how multiple LiveKit nodes share one redis for room affinity.