docs(deploy): LiveKit SFU provisioning — phase 3 (ops runbook)

Step-by-step to enable meetings SFU: generate key/secret, .env vars, DNS record,
NPM proxy host for wss signaling, VPS firewall for UDP media + TCP fallback, deploy,
verify. Includes the one-line rollback to mesh (remove the LIVEKIT_* vars).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 13:21:44 +05:30
parent 6118d59c5c
commit 47b6f475e6
+55
View File
@@ -184,6 +184,61 @@ an "unknown publisher" warning — supply an EV/OV code-signing cert to remove i
--- ---
## Meetings SFU (LiveKit) — optional, scales meetings past ~5 people
By default meetings use a **P2P mesh** (each person sends video to every other person), which
degrades past ~5 participants. Enabling **LiveKit** routes media through an SFU so each person
uploads once — rooms scale to 20-50+. It's **fully optional and config-gated**: until you set the
three `LIVEKIT_*` vars, the app keeps using the mesh, unchanged. The `livekit` service is already
in `docker-compose.yml`; these steps turn it on.
**1. Generate an API key + secret** (any two random strings; keep them secret):
```bash
echo "LIVEKIT_API_KEY=$(openssl rand -hex 8)"
echo "LIVEKIT_API_SECRET=$(openssl rand -hex 24)"
```
Add those two lines to the server's `.env`, plus the public signaling URL:
```
LIVEKIT_URL=wss://livekit.bizgaze.com
LIVEKIT_API_KEY=<from above>
LIVEKIT_API_SECRET=<from above>
```
The app mints join tokens with the secret (server-side only); the same key/secret reach the
`livekit` container via `LIVEKIT_KEYS` (docker-compose reads them from this same `.env`).
**2. DNS**: point `livekit.bizgaze.com` (A record) at the server — `118.95.33.89`.
**3. NPM proxy host** for the signaling WebSocket (LiveKit media does NOT go through NPM):
- Domain `livekit.bizgaze.com` → **Forward to** `livekit:7880` (scheme `http`).
- **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.
**5. Deploy** (starts the livekit container alongside the app):
```bash
cd /opt/bizgaze-support && ./deploy.sh
docker compose ps # expect both bizgaze-support AND bizgaze-livekit "Up"
```
**6. Verify**:
```bash
curl https://remote.bizgaze.com/api/meetings/config # expect {"sfu":true,"url":"wss://livekit.bizgaze.com"}
curl -I https://livekit.bizgaze.com # 200/426 (WS endpoint reachable via NPM+TLS)
docker logs bizgaze-livekit --tail 30 # "starting LiveKit server", no key errors
```
Then start a meeting in the app and confirm 3+ participants see each other. To roll back to mesh,
just remove the `LIVEKIT_*` vars from `.env` and redeploy — no code change.
---
## Verify ## Verify
```bash ```bash