1 Commits

Author SHA1 Message Date
bd7e323f9e TURN fixes
All checks were successful
cc-ci/testme cc-ci: success
Mirror of upstream coop-cloud/lasuite-meet#6:
- fix: resolve TURN_DOMAIN default at .env layer (compose.yml does not
  recursively expand nested ${...} references)
- docs: document host UDP buffer sysctl tuning for LiveKit
- docs: mention Chrome required on mobile
- docs: fix ports table formatting

Upstream: https://git.coopcloud.tech/coop-cloud/lasuite-meet/pulls/6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 18:48:07 +00:00
3 changed files with 43 additions and 8 deletions

View File

@ -82,7 +82,9 @@ LIVEKIT_NODE_IP=
#LIVEKIT_TURN_ENABLED=false #LIVEKIT_TURN_ENABLED=false
## TURN domain — must resolve to this server's IP. ## TURN domain — must resolve to this server's IP.
## Defaults to LIVEKIT_DOMAIN, which works for TURN/UDP setups. ## Defaults to LIVEKIT_DOMAIN, which works for TURN/UDP setups.
#TURN_DOMAIN=turn.example.com ## NOTE: must be set here, not as a compose-level `:-` default —
## docker-compose does not recursively expand nested `${...}` references.
TURN_DOMAIN=${LIVEKIT_DOMAIN}
## TURN/UDP port (default: 443). Recommended because UDP 443 is rarely ## TURN/UDP port (default: 443). Recommended because UDP 443 is rarely
## blocked and doesn't conflict with Traefik's TCP 443. ## blocked and doesn't conflict with Traefik's TCP 443.
#TURN_UDP_PORT=443 #TURN_UDP_PORT=443

View File

@ -89,20 +89,53 @@ Then redeploy the app, and automated e-mail sending should work:
* **One instance per server.** LiveKit requires host-published ports (7881, 7882, 443, 30000-30009) which can only be bound once per host. * **One instance per server.** LiveKit requires host-published ports (7881, 7882, 443, 30000-30009) which can only be bound once per host.
* **Server must have a direct public IP.** LiveKit's built-in TURN server does not work on servers behind a NAT gateway due to hairpin NAT issues. Configuring hairpin NAT on the gateway may be possible but has not been successfully tested yet. * **Server must have a direct public IP.** LiveKit's built-in TURN server does not work on servers behind a NAT gateway due to hairpin NAT issues. Configuring hairpin NAT on the gateway may be possible but has not been successfully tested yet.
* **Mobile browser must be Chrome** - there are various open issues wrt Firefox and WebRTC, so on mobile you have
to use a chromium based browser, else the connections fail!
## Network ports ## Network ports
This recipe publishes ports directly on the host for WebRTC media transport. These carry raw RTP media packets and are not routed through Traefik. The WebSocket signaling endpoint (`wss://LIVEKIT_DOMAIN`) is routed through Traefik as normal. This recipe publishes ports directly on the host for WebRTC media transport. These carry raw RTP media packets and are not routed through Traefik. The WebSocket signaling endpoint (`wss://LIVEKIT_DOMAIN`) is routed through Traefik as normal.
| Port | Protocol | Purpose | - **7881/TCP** — WebRTC ICE over TCP (fallback when UDP is blocked)
|------|----------|---------| - **7882/UDP** — WebRTC ICE over UDP (primary media transport)
| 7881 | TCP | WebRTC ICE over TCP (fallback when UDP is blocked) | - **443/UDP** — TURN relay (enabled by default via `compose.turn.yml`)
| 7882 | UDP | WebRTC ICE over UDP (primary media transport) | - **30000-30009/UDP** — TURN relay allocation ports
| 443 | UDP | TURN relay (enabled by default via `compose.turn.yml`) |
| 30000-30009 | UDP | TURN relay allocation ports |
Your firewall must allow inbound traffic on these ports. Your firewall must allow inbound traffic on these ports.
### Host kernel tuning
LiveKit logs a warning at startup if the kernel's UDP socket buffers are too small:
```
WARN livekit rtcconfig/rtc_unix.go:31 UDP receive buffer is too small for a production set-up {"current": 425984, "suggested": 5000000}
```
The Linux default (`net.core.rmem_max = 212992`) is well under what LiveKit needs once
several participants are forced through the TURN relay path. The resulting packet
loss shows up as `dtls timeout: read/write timeout: context deadline exceeded` on
publisher transports, intermittent media stalls, or one peer seeing a black tile
while the other sees video.
These sysctls are read by LiveKit when it opens its UDP sockets, so they must be
set on the **host** (not in the container) before the LiveKit container starts.
On the host, create `/etc/sysctl.d/99-livekit.conf`:
```
net.core.rmem_max = 7500000
net.core.wmem_max = 7500000
```
Then apply and restart the service:
```
sudo sysctl --system
docker service update --force <stack>_livekit
```
The warning should be gone from the LiveKit boot log.
### TURN server ### TURN server
TURN is enabled by default and helps users behind CGNAT/symmetric NAT connect to video calls. To disable it, remove `compose.turn.yml` from `COMPOSE_FILE` in your app config and set `LIVEKIT_TURN_ENABLED=false`. TURN is enabled by default and helps users behind CGNAT/symmetric NAT connect to video calls. To disable it, remove `compose.turn.yml` from `COMPOSE_FILE` in your app config and set `LIVEKIT_TURN_ENABLED=false`.

View File

@ -191,7 +191,7 @@ services:
- LIVEKIT_NODE_IP - LIVEKIT_NODE_IP
- LIVEKIT_FORCE_TCP=${LIVEKIT_FORCE_TCP:-false} - LIVEKIT_FORCE_TCP=${LIVEKIT_FORCE_TCP:-false}
- LIVEKIT_TURN_ENABLED=${LIVEKIT_TURN_ENABLED:-true} - LIVEKIT_TURN_ENABLED=${LIVEKIT_TURN_ENABLED:-true}
- TURN_DOMAIN=${TURN_DOMAIN:-${LIVEKIT_DOMAIN}} - TURN_DOMAIN=${TURN_DOMAIN}
- TURN_UDP_PORT=${TURN_UDP_PORT:-443} - TURN_UDP_PORT=${TURN_UDP_PORT:-443}
# WebRTC ICE ports must be published directly on the host. # WebRTC ICE ports must be published directly on the host.
# These carry raw RTP media, not HTTP — cannot be proxied through Traefik without extra traefik compose. # These carry raw RTP media, not HTTP — cannot be proxied through Traefik without extra traefik compose.