mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-03-29 11:59:59 +00:00
310 lines
10 KiB
Plaintext
310 lines
10 KiB
Plaintext
# Matrix RTC/Element Call Setup
|
|
|
|
:::info
|
|
This guide assumes that you are using docker compose for deployment. LiveKit only provides Docker images.
|
|
:::
|
|
|
|
## Instructions
|
|
|
|
### 1. Domain
|
|
|
|
LiveKit should live on its own domain or subdomain. In this guide we use `livekit.example.com` - this should be replaced with a domain you control.
|
|
|
|
Make sure the DNS record for the (sub)domain you plan to use is pointed to your server.
|
|
|
|
### 2. Services
|
|
|
|
Using LiveKit with Matrix requires two services - LiveKit itself, and a service (`lk-jwt-service`) that grants Matrix users permission to connect to it.
|
|
|
|
You must generate a key and secret to allow the Matrix service to authenticate with LiveKit. `LK_MATRIX_KEY` should be around 20 random characters, and `LK_MATRIX_SECRET` should be around 64. Remember to replace these with the actual values!
|
|
|
|
:::tip Generating the secrets
|
|
LiveKit provides a utility to generate secure random keys
|
|
```bash
|
|
docker run --rm livekit/livekit-server:latest generate-keys
|
|
```
|
|
:::
|
|
|
|
```yaml
|
|
services:
|
|
lk-jwt-service:
|
|
image: ghcr.io/element-hq/lk-jwt-service:latest
|
|
container_name: lk-jwt-service
|
|
environment:
|
|
- LIVEKIT_JWT_BIND=:8081
|
|
- LIVEKIT_URL=wss://livekit.example.com
|
|
- LIVEKIT_KEY=LK_MATRIX_KEY
|
|
- LIVEKIT_SECRET=LK_MATRIX_SECRET
|
|
- LIVEKIT_FULL_ACCESS_HOMESERVERS=example.com
|
|
restart: unless-stopped
|
|
ports:
|
|
- "8081:8081"
|
|
|
|
livekit:
|
|
image: livekit/livekit-server:latest
|
|
container_name: livekit
|
|
command: --config /etc/livekit.yaml
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./livekit.yaml:/etc/livekit.yaml:ro
|
|
network_mode: "host" # /!\ LiveKit binds to all addresses by default.
|
|
# Make sure port 7880 is blocked by your firewall to prevent access bypassing your reverse proxy
|
|
# Alternatively, uncomment the lines below and comment `network_mode: "host"` above to specify port mappings.
|
|
# ports:
|
|
# - "127.0.0.1:7880:7880/tcp"
|
|
# - "7881:7881/tcp"
|
|
# - "50100-50200:50100-50200/udp"
|
|
```
|
|
|
|
Next, we need to configure LiveKit. In the same directory, create `livekit.yaml` with the following content - remembering to replace `LK_MATRIX_KEY` and `LK_MATRIX_SECRET` with the values you generated:
|
|
|
|
```yaml
|
|
port: 7880
|
|
bind_addresses:
|
|
- ""
|
|
rtc:
|
|
tcp_port: 7881
|
|
port_range_start: 50100
|
|
port_range_end: 50200
|
|
use_external_ip: true
|
|
enable_loopback_candidate: false
|
|
keys:
|
|
LK_MATRIX_KEY: LK_MATRIX_SECRET
|
|
```
|
|
|
|
#### Firewall hints
|
|
|
|
You will need to allow ports `7881/tcp` and `50100:50200/udp` through your firewall. If you use UFW, the commands are: `ufw allow 7881/tcp` and `ufw allow 50100:50200/udp`.
|
|
|
|
### 3. Telling clients where to find LiveKit
|
|
|
|
To tell clients where to find LiveKit, you need to add the address of your `lk-jwt-service` to the `[global.matrix_rtc]` config section using the `foci` option.
|
|
|
|
The variable should be a list of servers serving as MatrixRTC endpoints. Clients discover these via the `/_matrix/client/v1/rtc/transports` endpoint (MSC4143).
|
|
|
|
```toml
|
|
[global.matrix_rtc]
|
|
foci = [
|
|
{ type = "livekit", livekit_service_url = "https://livekit.example.com" },
|
|
]
|
|
```
|
|
|
|
Remember to replace the URL with the address you are deploying your instance of lk-jwt-service to.
|
|
|
|
### 4. Configure your Reverse Proxy
|
|
|
|
Reverse proxies can be configured in many different ways - so we can't provide a step by step for this.
|
|
|
|
By default, all routes should be forwarded to LiveKit with the exception of the following path prefixes, which should be forwarded to the JWT/Authentication service:
|
|
|
|
- `/sfu/get`
|
|
- `/healthz`
|
|
- `/get_token`
|
|
|
|
<details>
|
|
<summary>Example caddy config</summary>
|
|
```
|
|
livekit.example.com {
|
|
|
|
# for lk-jwt-service
|
|
@lk-jwt-service path /sfu/get* /healthz* /get_token*
|
|
route @lk-jwt-service {
|
|
reverse_proxy 127.0.0.1:8081
|
|
}
|
|
|
|
# for livekit
|
|
reverse_proxy 127.0.0.1:7880
|
|
}
|
|
```
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Example nginx config</summary>
|
|
```
|
|
server {
|
|
server_name livekit.example.com;
|
|
|
|
# for lk-jwt-service
|
|
location ~ ^/(sfu/get|healthz|get_token) {
|
|
proxy_pass http://127.0.0.1:8081$request_uri;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Host $http_host;
|
|
proxy_buffering off;
|
|
}
|
|
|
|
# for LiveKit
|
|
location / {
|
|
proxy_pass http://127.0.0.1:7880$request_uri;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Host $http_host;
|
|
proxy_buffering off;
|
|
|
|
# websocket
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
}
|
|
}
|
|
```
|
|
|
|
Note that for websockets to work, you need to have this somewhere outside your server block:
|
|
```
|
|
map $http_upgrade $connection_upgrade {
|
|
default upgrade;
|
|
'' close;
|
|
}
|
|
```
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Example traefik router</summary>
|
|
```
|
|
# on LiveKit itself
|
|
traefik.http.routers.livekit.rule=Host(`livekit.example.com`)
|
|
# on the JWT service
|
|
traefik.http.routers.livekit-jwt.rule=Host(`livekit.example.com`) && (PathPrefix(`/sfu/get`) || PathPrefix(`/healthz`) || PathPrefix(`/get_token`))
|
|
```
|
|
</details>
|
|
|
|
|
|
### 6. Start Everything
|
|
|
|
Start up the services using your usual method - for example `docker compose up -d`.
|
|
|
|
## Additional Configuration
|
|
|
|
### Using LiveKit's built in TURN server
|
|
|
|
LiveKit includes a built in TURN server which can be used in place of an external option. This TURN server will only work with LiveKit, so you can't use it for legacy Matrix calling or anything else.
|
|
|
|
If you don't want to set up a separate TURN server, you can enable this with the following changes:
|
|
|
|
```yaml
|
|
### add this to livekit.yaml ###
|
|
turn:
|
|
enabled: true
|
|
udp_port: 3478
|
|
relay_range_start: 50300
|
|
relay_range_end: 50400
|
|
domain: livekit.example.com
|
|
```
|
|
|
|
```yaml
|
|
### Add these to docker-compose ###
|
|
ports:
|
|
- "3478:3478/udp"
|
|
- "50300-50400:50300-50400/udp"
|
|
```
|
|
|
|
### Integration with an external TURN server
|
|
|
|
If you've already set up coturn, there may be a port clash between the two services. To fix this, make sure coturn's `min-port` and `max-port` do not overlap with LiveKit's range:
|
|
|
|
```ini
|
|
min-port=50201
|
|
max-port=65535
|
|
```
|
|
|
|
To improve LiveKit's reliability, you can configure it to use your coturn server.
|
|
|
|
Generate a long random secret for LiveKit, and add it to your coturn config under the `static-auth-secret` option. You can add as many secrets as you want, so set a different one for each thing using your TURN server.
|
|
|
|
Then configure LiveKit, making sure to replace `COTURN_SECRET` with the ones you generated:
|
|
|
|
```yaml
|
|
# livekit.yaml
|
|
rtc:
|
|
turn_servers:
|
|
- host: coturn.example.com
|
|
port: 3478
|
|
protocol: tcp
|
|
secret: "COTURN_SECRET"
|
|
- host: coturn.example.com
|
|
port: 5349
|
|
protocol: tls # Only if you've set up TLS in your coturn
|
|
secret: "COTURN_SECRET"
|
|
- host: coturn.example.com
|
|
port: 3478
|
|
protocol: udp
|
|
secret: "COTURN_SECRET"
|
|
```
|
|
|
|
## Testing
|
|
|
|
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow](https://github.com/element-hq/lk-jwt-service?tab=readme-ov-file#%EF%B8%8F-how-it-works--token-exchange-flow). First, request an OpenID token from your Matrix server:
|
|
|
|
```bash
|
|
curl -X POST -H "Authorization: Bearer <session-access-token>" \
|
|
https://matrix.example.com/_matrix/client/v3/user/@user:example.com/openid/request_token
|
|
```
|
|
|
|
Your `<session-access-token>` can be found in your client's settings, or via [this website](https://timedout.uk/mxtoken.html). The step above will respond with an `access_token` for use with the lk-jwt-service.
|
|
|
|
Next, create a `payload.json` file with the following content:
|
|
|
|
<details>
|
|
|
|
<summary>`payload.json`</summary>
|
|
|
|
```json
|
|
{
|
|
"room_id": "abc",
|
|
"slot_id": "xyz",
|
|
"openid_token": {
|
|
"matrix_server_name": "example.com",
|
|
"access_token": "<access_token>",
|
|
"token_type": "Bearer"
|
|
},
|
|
"member": {
|
|
"id": "xyz",
|
|
"claimed_device_id": "DEVICEID",
|
|
"claimed_user_id": "@user:example.com"
|
|
}
|
|
}
|
|
```
|
|
|
|
Replace `matrix_server_name` and `claimed_user_id` with your information, and `<access_token>` with the one you got from the previous step. Other values can be left as-is.
|
|
|
|
</details>
|
|
|
|
You can then send this payload to the lk-jwt-service with:
|
|
|
|
```bash
|
|
curl -X POST -d @payload.json https://livekit.example.com/get_token
|
|
```
|
|
|
|
The JWT service will respond with a `jwt` token. Use this token to test at the [LiveKit Connection Tester](https://livekit.io/connection-test) - if everything works there, then you have set up LiveKit successfully!
|
|
<<<<<<< HEAD
|
|
|
|
## Caveats
|
|
|
|
When deploying on servers with disabled federation (`enable_registration = false`), Livekit will fail as it can't fetch the required [OpenID endpoint](https://spec.matrix.org/v1.17/server-server-api/#get_matrixfederationv1openiduserinfo) via federation paths. You can find a workaround for this limitation [here](https://forgejo.ellis.link/continuwuation/continuwuity/issues/1440).
|
|
=======
|
|
>>>>>>> 5244c55 (docs: apply changes from feedback)
|
|
|
|
## Related Documentation
|
|
|
|
Guides:
|
|
|
|
- [Element Call self-hosting documentation](https://github.com/element-hq/element-call/blob/livekit/docs/self-hosting.md)
|
|
<<<<<<< HEAD
|
|
- [Community guide with overview of Livekit's mechanisms](https://tomfos.tr/matrix/livekit/)
|
|
- [Community guide (using systemd)](https://blog.kimiblock.top/2024/12/24/hosting-element-call/)
|
|
=======
|
|
- [Community guide with overview of LiveKit's mechanisms](https://tomfos.tr/matrix/livekit/)
|
|
- [Community guide using systemd](https://blog.kimiblock.top/2024/12/24/hosting-element-call/)
|
|
>>>>>>> 5244c55 (docs: apply changes from feedback)
|
|
|
|
Specifications:
|
|
|
|
- [MatrixRTC proposal](https://github.com/matrix-org/matrix-spec-proposals/pull/4143)
|
|
- [LiveKit proposal](https://github.com/matrix-org/matrix-spec-proposals/pull/4195)
|
|
|
|
Source codes:
|
|
|
|
- [Element Call](https://github.com/element-hq/element-call)
|
|
- [lk-jwt-service](https://github.com/element-hq/lk-jwt-service)
|
|
- [LiveKit server](https://github.com/livekit/livekit)
|