Sanitized mirror from private repository - 2026-04-19 08:15:48 UTC
This commit is contained in:
162
docs/services/individual/matrixrtc-livekit.md
Normal file
162
docs/services/individual/matrixrtc-livekit.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# MatrixRTC / LiveKit — Element X Calls
|
||||
|
||||
**Last updated:** 2026-03-19
|
||||
|
||||
MatrixRTC enables voice/video calls in Element X using a LiveKit SFU backend. Both homeservers (`mx.vish.gg` and `matrix.thevish.io`) share the same LiveKit SFU on `matrix-ubuntu`.
|
||||
|
||||
---
|
||||
|
||||
## Service Overview
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Host** | matrix-ubuntu (`192.168.0.154`) |
|
||||
| **Matrix homeservers** | `mx.vish.gg` (synapse-mx.service) and `matrix.thevish.io` (synapse.service) — both on Synapse 1.148.0 |
|
||||
| **Compose file** | `hosts/vms/matrix-ubuntu/livekit.yml` (deployed manually at `/opt/livekit/`) |
|
||||
| **LiveKit version** | 1.9.12 |
|
||||
| **JWT service** | `ghcr.io/element-hq/lk-jwt-service:latest-ci` |
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Element X ──→ mx.vish.gg (.well-known) ──→ livekit.mx.vish.gg/livekit/jwt (JWT service)
|
||||
──→ matrix.thevish.io (.well-known) ──→ livekit.mx.vish.gg/livekit/sfu (LiveKit SFU)
|
||||
livekit.mx.vish.gg/ (LiveKit WS)
|
||||
```
|
||||
|
||||
Both homeservers share the same LiveKit backend.
|
||||
|
||||
- **NPM** on Calypso proxies `livekit.mx.vish.gg` → matrix-ubuntu
|
||||
- `/livekit/jwt/` → JWT service port 8089 (container 8080)
|
||||
- `/livekit/sfu/` → LiveKit SFU port 7880
|
||||
- `/` → LiveKit SFU port 7880 (WebSocket for direct connections)
|
||||
- **DNS**: `livekit.mx.vish.gg` A record unproxied → `184.23.52.14` (home WAN)
|
||||
- **TLS**: Let's Encrypt cert issued via Cloudflare DNS challenge on matrix-ubuntu, copied to NPM as `npm-7`
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Endpoint | URL | Purpose |
|
||||
|----------|-----|---------|
|
||||
| JWT service healthz | `https://livekit.mx.vish.gg/livekit/jwt/healthz` | Health check |
|
||||
| JWT service SFU get | `https://livekit.mx.vish.gg/livekit/jwt/sfu/get` | Token exchange |
|
||||
| LiveKit SFU WS | `wss://livekit.mx.vish.gg/livekit/sfu/` | WebSocket signalling |
|
||||
| LiveKit HTTP | `https://livekit.mx.vish.gg/` | SFU API |
|
||||
| .well-known | `https://mx.vish.gg/.well-known/matrix/client` | RTC foci advertisement |
|
||||
|
||||
---
|
||||
|
||||
## Configuration Files on matrix-ubuntu
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `/opt/livekit/docker-compose.yml` | LiveKit + JWT service deployment |
|
||||
| `/opt/livekit/livekit.yaml` | LiveKit SFU config (keys, RTC ports, external IP) |
|
||||
| `/opt/synapse-mx/homeserver.yaml` | Synapse config (MSCs, rate limits) |
|
||||
| `/etc/nginx/sites-available/mx-vish-gg` | nginx serving `.well-known` and Element static files |
|
||||
| `/etc/letsencrypt/live/livekit.mx.vish.gg/` | TLS cert (auto-renews, copies to NPM via deploy hook) |
|
||||
|
||||
---
|
||||
|
||||
## Synapse homeserver.yaml additions
|
||||
|
||||
```yaml
|
||||
# MatrixRTC / Element Call support
|
||||
experimental_features:
|
||||
msc3266_enabled: true # Room Summary API (knocking over federation)
|
||||
msc4222_enabled: true # state_after in sync v2
|
||||
msc4140_enabled: true # Delayed events (call participation signalling)
|
||||
|
||||
max_event_delay_duration: 24h
|
||||
|
||||
rc_message:
|
||||
per_second: 0.5
|
||||
burst_count: 30
|
||||
|
||||
rc_delayed_event_mgmt:
|
||||
per_second: 1
|
||||
burst_count: 20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## .well-known/matrix/client
|
||||
|
||||
Served by nginx at `https://mx.vish.gg/.well-known/matrix/client`:
|
||||
|
||||
```json
|
||||
{
|
||||
"m.homeserver": {"base_url": "https://mx.vish.gg"},
|
||||
"org.matrix.msc4143.rtc_foci": [
|
||||
{
|
||||
"type": "livekit",
|
||||
"livekit_service_url": "https://livekit.mx.vish.gg/livekit/jwt"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LiveKit SFU config (/opt/livekit/livekit.yaml)
|
||||
|
||||
Key settings:
|
||||
- `use_external_ip: true` — auto-detects WAN IP `184.23.52.14`
|
||||
- `use_ice_lite: true` — optimised for server-side NAT traversal
|
||||
- `room.auto_create: false` — only lk-jwt-service creates rooms (security)
|
||||
- RTC ports: 7880 TCP (API/WS), 7881 TCP (RTC), 50000-60000 UDP (media)
|
||||
- **Note:** UDP 50000-60000 port range is NOT currently forwarded on the router — TURN relay is used instead via coturn at `turn:mx.vish.gg:3479`
|
||||
|
||||
---
|
||||
|
||||
## TLS Certificate Renewal
|
||||
|
||||
Cert is issued on matrix-ubuntu via certbot + Cloudflare DNS plugin. A deploy hook copies it to NPM on Calypso after renewal:
|
||||
|
||||
```
|
||||
/etc/letsencrypt/renewal-hooks/deploy/copy-to-npm.sh
|
||||
```
|
||||
|
||||
If the hook fails, manually copy:
|
||||
```bash
|
||||
ssh matrix-ubuntu
|
||||
sudo cp /etc/letsencrypt/live/livekit.mx.vish.gg/fullchain.pem \
|
||||
/tmp/lk.crt
|
||||
sudo cp /etc/letsencrypt/live/livekit.mx.vish.gg/privkey.pem \
|
||||
/tmp/lk.key
|
||||
scp -P 62000 /tmp/lk.crt Vish@100.103.48.78:/volume1/docker/nginx-proxy-manager/data/custom_ssl/npm-7/fullchain.pem
|
||||
scp -P 62000 /tmp/lk.key Vish@100.103.48.78:/volume1/docker/nginx-proxy-manager/data/custom_ssl/npm-7/privkey.pem
|
||||
ssh -p 62000 Vish@100.103.48.78 'sudo /usr/local/bin/docker exec nginx-proxy-manager nginx -s reload'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Calls not working in Element X
|
||||
1. Check `.well-known` is advertising foci: `curl https://mx.vish.gg/.well-known/matrix/client`
|
||||
2. Check JWT service: `curl https://livekit.mx.vish.gg/livekit/jwt/healthz`
|
||||
3. Check LiveKit is running: `ssh matrix-ubuntu "sudo docker ps | grep livekit"`
|
||||
4. Check LiveKit logs: `ssh matrix-ubuntu "sudo docker logs livekit 2>&1 | tail -20"`
|
||||
|
||||
### Stuck calls
|
||||
See [How to resolve stuck MatrixRTC calls](https://sspaeth.de/2025/02/how-to-resolve-stuck-matrixrtc-calls/) — usually caused by delayed events not cleaning up.
|
||||
|
||||
### JWT service returns 400
|
||||
Normal for unauthenticated requests. Means the service is running correctly.
|
||||
|
||||
### Restarting services
|
||||
```bash
|
||||
ssh matrix-ubuntu
|
||||
cd /opt/livekit
|
||||
sudo docker compose restart
|
||||
```
|
||||
|
||||
### Restarting Synapse
|
||||
```bash
|
||||
ssh matrix-ubuntu
|
||||
sudo systemctl restart synapse-mx.service
|
||||
```
|
||||
Reference in New Issue
Block a user