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:
@@ -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
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user