fix(livekit): single UDP media port + pin node_ip for the NAT'd server
The prod box is behind NAT (private 192.168.88.61 behind public 118.95.33.89), so LiveKit auto-IP-detection would pick the wrong (outbound) address. Pin rtc.node_ip=118.95.33.89 and collapse media to one UDP port (50000) + TCP 7881 to minimize the upstream gateway port-forward the network team must add. Docs updated with the exact forward table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -213,14 +213,21 @@ The app mints join tokens with the secret (server-side only); the same key/secre
|
||||
- **Websockets Support: ON**. Request an SSL cert (Let's Encrypt) + Force SSL.
|
||||
- NPM reaches `livekit:7880` by container name — both are on `nginx_proxy_manager_default`.
|
||||
|
||||
**4. Open the media ports on the VPS firewall** (these are host-published by the compose service,
|
||||
bypassing NPM — WebRTC media can't traverse an L7 proxy):
|
||||
```bash
|
||||
ufw allow 50000:50100/udp # WebRTC media (must match livekit.yaml port range)
|
||||
ufw allow 7881/tcp # WebRTC-over-TCP fallback for restrictive networks
|
||||
```
|
||||
If the VPS is behind NAT and LiveKit can't auto-detect its public IP, set `rtc.node_ip` in
|
||||
`livekit.yaml` to `118.95.33.89` and redeploy.
|
||||
**4. Media ports — NAT port-forward (REQUIRED here).** This box sits **behind NAT**: its only
|
||||
interface is a private `192.168.88.61`; the public `118.95.33.89` (DNS) is mapped by an upstream
|
||||
gateway. WebRTC media can't traverse NPM (L7), so the gateway/router must forward the media ports
|
||||
to the box. To keep the ask minimal, LiveKit is configured for **one** UDP port + one TCP fallback:
|
||||
|
||||
Ask whoever controls the network/gateway to forward, from `118.95.33.89` → `192.168.88.61`:
|
||||
| Port | Proto | Purpose |
|
||||
|------|-------|---------|
|
||||
| 50000 | UDP | WebRTC media (all participants mux over this one port) |
|
||||
| 7881 | TCP | WebRTC-over-TCP fallback (restrictive client networks) |
|
||||
|
||||
`livekit.yaml` already pins `rtc.node_ip: 118.95.33.89` (auto-detect would pick the wrong outbound
|
||||
IP behind this NAT). The host's local `ufw` is inactive, so no host-firewall change is needed — the
|
||||
only requirement is the upstream port-forward above. Until it exists, signaling connects but media
|
||||
won't flow (participants see each other's tiles but no video/audio).
|
||||
|
||||
**5. Deploy** (the livekit service is behind a `sfu` compose profile, so it stays dormant on a
|
||||
normal deploy — start it explicitly):
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ services:
|
||||
- ./livekit.yaml:/etc/livekit.yaml:ro
|
||||
ports:
|
||||
- "7881:7881" # WebRTC over TCP (fallback)
|
||||
- "50000-50100:50000-50100/udp" # WebRTC media (UDP) — must match livekit.yaml port range
|
||||
- "50000:50000/udp" # single WebRTC media UDP port (must match livekit.yaml rtc.udp_port)
|
||||
networks:
|
||||
- npm
|
||||
|
||||
|
||||
+6
-4
@@ -7,10 +7,12 @@
|
||||
port: 7880 # signaling (HTTP/WS) — NPM proxies wss://livekit.bizgaze.com -> here
|
||||
rtc:
|
||||
tcp_port: 7881 # WebRTC-over-TCP fallback (restrictive networks)
|
||||
port_range_start: 50000 # WebRTC media (UDP) — keep in sync with the published range in compose
|
||||
port_range_end: 50100
|
||||
use_external_ip: true # discover the public IP for ICE candidates (VPS). Or set node_ip below.
|
||||
# node_ip: 118.95.33.89 # uncomment + set if use_external_ip can't detect the public IP
|
||||
udp_port: 50000 # SINGLE UDP media port (all participants mux over it) — minimizes
|
||||
# the NAT port-forward to one UDP + one TCP port.
|
||||
# This box sits behind NAT (private 192.168.88.61 behind public 118.95.33.89). Auto-detection
|
||||
# would find the wrong (outbound) IP, so pin the inbound public IP clients actually reach.
|
||||
use_external_ip: false
|
||||
node_ip: 118.95.33.89
|
||||
|
||||
# Embedded TURN over TLS on 443 helps clients on locked-down networks. Left off by default because
|
||||
# NPM already owns 443; enable via a dedicated hostname + NPM stream if you need it (see DEPLOY.md).
|
||||
|
||||
Reference in New Issue
Block a user