mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-13 12:16:54 +00:00
565 lines
20 KiB
Plaintext
565 lines
20 KiB
Plaintext
import { Tab, Tabs } from '@rspress/core/theme';
|
|
|
|
# MatrixRTC/LiveKit Setup
|
|
|
|
This guide assumes that you are using `docker compose` for deployment.
|
|
|
|
:::tip
|
|
You can find help setting up MatrixRTC in our support room - [`#continuwuity:continuwuity.org`][support-room]
|
|
:::
|
|
|
|
[support-room]: https://matrix.to/#/%23continuwuity:continuwuity.org
|
|
|
|
## Instructions
|
|
|
|
### 1. Set up your 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. Set up the LiveKit services
|
|
|
|
Using LiveKit with Matrix requires two services - LiveKit itself, and a brokering 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
|
|
# API Key: APIUxUnMnSkuFWV
|
|
# API Secret: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
|
|
```
|
|
:::
|
|
|
|
Create a `docker-compose.yml` file as following:
|
|
|
|
```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 # your LiveKit domain
|
|
- LIVEKIT_FULL_ACCESS_HOMESERVERS=example.com # your server_name
|
|
# Replace these with the generated values as above
|
|
- LIVEKIT_KEY=LK_MATRIX_KEY # APIUxUnMnSkuFWV
|
|
- LIVEKIT_SECRET=LK_MATRIX_SECRET # t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
|
|
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 out `network_mode: "host"`
|
|
# above to use bridge networking and manually 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
|
|
# replace these with your key-secret pair. Example:
|
|
# APIUxUnMnSkuFWV: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
|
|
|
|
# do not create rooms by default
|
|
room:
|
|
auto_create: false
|
|
```
|
|
|
|
Consult [`config-sample.yaml`][livekit-config-sample-yaml] for all LiveKit options.
|
|
|
|
[livekit-config-sample-yaml]: https://github.com/livekit/livekit/blob/master/config-sample.yaml
|
|
|
|
#### 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 your `lk-jwt-service`'s address to the `foci` field of the `[global.matrix_rtc]` section of your Continuwuity config file.
|
|
|
|
The variable should be a list of servers serving as MatrixRTC endpoints. Replace the URL with the address you are deploying your instance of lk-jwt-service to:
|
|
|
|
```toml
|
|
[global.matrix_rtc]
|
|
foci = [
|
|
{ type = "livekit", livekit_service_url = "https://livekit.example.com" },
|
|
]
|
|
```
|
|
|
|
If you configure Continuwuity via environment variables, use the following:
|
|
|
|
```bash
|
|
CONTINUWUITY_MATRIX_RTC__FOCI=[{ type = "livekit", livekit_service_url = "https://livekit.example.com" }]
|
|
```
|
|
|
|
This will expose LiveKit information on the following endpoints for clients to discover:
|
|
|
|
- `/_matrix/client/unstable/org.matrix.msc4143/rtc/transports` (MSC4143 unstable, behind auth)
|
|
- `/.well-known/matrix/client` (fallback, not behind auth. Only enabled if `[global.well_known].client` is set)
|
|
|
|
### 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.
|
|
|
|
All paths should be forwarded to LiveKit by default, with the exception of the following path prefixes, which should be forwarded to the JWT/Authentication service:
|
|
|
|
- `/sfu/get`
|
|
- `/healthz`
|
|
- `/get_token`
|
|
|
|
<Tabs groupId="reverse-proxy">
|
|
<Tab label="Caddy (on host)">
|
|
|
|
```ini
|
|
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
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab label="Caddy (in container)">
|
|
|
|
Requires `livekit` and `lk-jwt-service` to be on the same Docker bridge network as Caddy.
|
|
|
|
```ini
|
|
livekit.example.com {
|
|
|
|
# for lk-jwt-service
|
|
@lk-jwt-service path /sfu/get* /healthz* /get_token*
|
|
route @lk-jwt-service {
|
|
reverse_proxy lk-jwt-service:8081
|
|
}
|
|
|
|
# for livekit
|
|
reverse_proxy livekit:7880
|
|
}
|
|
```
|
|
</Tab>
|
|
<Tab label="Caddy (via Docker labels)">
|
|
|
|
This setup assumes all containers share the same bridge network.
|
|
|
|
|
|
```yaml title="docker-compose.yml" fold height="200" file="../public/calls/livekit.docker-compose.with-caddy-labels.yml"
|
|
|
|
```
|
|
|
|
([view raw](/calls/livekit.docker-compose.with-caddy-labels.yml))
|
|
|
|
</Tab>
|
|
<Tab label="Traefik (via Docker labels)">
|
|
|
|
Requires `livekit` and `lk-jwt-service` to be on the same Docker bridge network as Traefik.
|
|
|
|
```
|
|
# 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`))
|
|
```
|
|
|
|
</Tab>
|
|
<Tab label="nginx">
|
|
|
|
```nginx title="nginx.conf" file="../public/calls/livekit.nginx.conf"
|
|
|
|
```
|
|
|
|
([view raw](/calls/livekit.nginx.conf))
|
|
|
|
Note: To enable WebSockets proxying functionality, include the following snippet somewhere outside your server block:
|
|
```nginx
|
|
map $http_upgrade $connection_upgrade {
|
|
default upgrade;
|
|
'' close;
|
|
}
|
|
```
|
|
|
|
See nginx's [WebSocket proxying documentation][nginx-websockets] for further details.
|
|
|
|
[nginx-websockets]: https://nginx.org/en/docs/http/websocket.html
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
### 6. Start Everything
|
|
|
|
Start up the services using your usual method - for example `docker compose up -d`.
|
|
|
|
## Testing
|
|
|
|
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow][token-exchange-flow]. Follow the steps below while checking Docker logs (`docker compose logs --follow`), in order to help [troubleshooting](#troubleshooting) any issues.
|
|
|
|
[token-exchange-flow]: https://github.com/element-hq/lk-jwt-service/tree/v0.6.0#%EF%B8%8F-how-it-works--token-exchange-flow
|
|
|
|
First, you will need an access token for your current login session. These can be found in your client's settings or obtained via [this website][starstruck-mxtoken2].
|
|
|
|
[starstruck-mxtoken2]: https://starstruck.systems/matrix/tools/mxtoken2
|
|
|
|
Then, using that token, fetch the discovery endpoints for MatrixRTC services:
|
|
|
|
```bash
|
|
curl -H "Authorization: Bearer <session-access-token>" \
|
|
https://matrix.example.com/_matrix/client/unstable/org.matrix.msc4143/rtc/transports
|
|
```
|
|
|
|
In the output, you should see the LiveKit URL matching the one [configured above](#3-telling-clients-where-to-find-livekit).
|
|
|
|
With the same token, request another OpenID token for use with the lk-jwt-service:
|
|
|
|
```bash
|
|
curl -X POST -H "Authorization: Bearer <session-access-token>" \
|
|
https://matrix.example.com/_matrix/client/v3/user/@user:example.com/openid/request_token
|
|
```
|
|
|
|
You will see a response as below:
|
|
|
|
```json
|
|
{"access_token":"<openid_access_token>","token_type":"Bearer","matrix_server_name":"example.com","expires_in":3600}
|
|
```
|
|
|
|
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": "<openid_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 `<openid_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:
|
|
|
|
```bash
|
|
curl -X POST -d @payload.json https://livekit.example.com/get_token
|
|
```
|
|
|
|
The lk-jwt-service will, after checking against Continuwuity, answer with a `jwt` token to [create a LiveKit media room](#livekit-cli):
|
|
|
|
```json
|
|
{"url":"wss://livekit.example.com","jwt":"a_really_really_long_string"}
|
|
```
|
|
|
|
Use this token to test at the [LiveKit Connection Tester][livekit-connection-test]. If everything works there, then you have set up LiveKit successfully!
|
|
|
|
[livekit-connection-test]: https://livekit.com/webrtc/connection-test
|
|
|
|
## Troubleshooting
|
|
|
|
To debug any issues, you can place a call or redo the Testing instructions, and check the container logs for any specific errors. Use `docker compose logs --follow` to follow these logs in real-time.
|
|
|
|
Before debugging, ensure the following prerequisites:
|
|
|
|
- The user has permissions to send call events into the room. See the Appendix section on [call modes](#call-modes) for more details.
|
|
- WebRTC is enabled, if using a browser client.
|
|
|
|
### Common errors in Element Call UI
|
|
|
|
- `MISSING_MATRIX_RTC_FOCUS`/`MISSING_MATRIX_RTC_TRANSPORT`: the client cannot find a suitable SFU. This is likely due to LiveKit being missing from Continuwuity's config file, and therefore not being exposed properly.
|
|
|
|
- `OPEN_ID_ERROR`: Your client can reach out to `lk-jwt-service`, but `lk-jwt-service` has problems authenticating you against Continuwuity. In this case, check `lk-jwt-service` logs for more details. The section below on [Docker loopback networking issues](#docker-loopback-networking-issues) may be of help.
|
|
|
|
- Calls fail to start with `ServerUnreachable` error: a LiveKit URL has been properly configured and exposed in Continuwuity, but the client cannot connect to it for some reason.
|
|
|
|
For browser-based clients, you can inspect connections using DevTools' Networking tab, to see which requests are erroring out. You may also want to toggle on Element Call's Developer tab via _Settings > Preferences > Developer mode_ \- various call details and advanced settings can be further tweaked there.
|
|
|
|
### Docker loopback networking issues
|
|
|
|
Some distros do not allow Docker containers to connect to the host's public IP, and this breaks connections from `lk-jwt-service` towards `livekit` and `continuwuity` if they're on the same host. This can be tested by the following command:
|
|
|
|
```bash
|
|
docker run --rm --net container:lk-jwt-service docker.io/curlimages/curl https://livekit.example.com
|
|
# --- some errors ---
|
|
```
|
|
|
|
To resolve this, follow the steps in [Docker loopback networking issues](../troubleshooting.mdx#docker-loopback-networking-issues) of the Troubleshooting page.
|
|
|
|
### Incorrect IP addresses for LiveKit
|
|
|
|
By default, LiveKit automatically finds its public IP address(es), which are reflected in the "Establishing WebRTC connection" section of the connection test page. If these IPs are incorrect, you may want to hardcode your own IP by doing the following:
|
|
|
|
```diff
|
|
### in your livekit.yaml ###
|
|
rtc:
|
|
# ... other configs here ...
|
|
- use_external_ip: true
|
|
+ use_external_ip: false
|
|
+ node_ip: "1.2.3.4"
|
|
```
|
|
|
|
Run the LiveKit tests again, and the new updated `node_ip` should be included as one of the candidates.
|
|
|
|
You may further restrict the advertised address to only the `node_ip` with the following configurations:
|
|
|
|
```diff
|
|
### in your livekit.yaml ###
|
|
rtc:
|
|
# ... other configs here ...
|
|
+ enable_loopback_candidate: false
|
|
+ interfaces:
|
|
+ includes: []
|
|
+ ips:
|
|
+ includes: [ "1.2.3.4/32" ]
|
|
```
|
|
|
|
## Related Documentation
|
|
|
|
Guides:
|
|
|
|
- [Element Call self-hosting documentation from element-hq][element-call-selfhosting]
|
|
- [Community guide with overview of LiveKit's mechanisms][tom-livekit-guide]
|
|
- [Community guide using systemd][kimiblock-livekit-guide]
|
|
|
|
[element-call-selfhosting]: https://github.com/element-hq/element-call/blob/livekit/docs/self-hosting.md
|
|
[tom-livekit-guide]: https://tomfos.tr/matrix/livekit/
|
|
[kimiblock-livekit-guide]: https://blog.kimiblock.top/2024/12/24/hosting-element-call/
|
|
|
|
Configurations:
|
|
|
|
- [Livekit's `config-sample.yaml`][livekit-config-sample-yaml] - LiveKit configuration file with full options
|
|
|
|
Specifications:
|
|
|
|
- [MSC4143: MatrixRTC \- Real-time communication over Matrix][MSC4143]
|
|
- [MSC4195: MatrixRTC Transport using LiveKit Backend][MSC4195]
|
|
- [MSC3401: Native Group VoIP Signalling][MSC3401] - state events for legacy calls
|
|
- [MSC4075: MatrixRTC invites and notifications][MSC4075] - for ringing users
|
|
- [MSC4354: Sticky Events][MSC4354] - for MatrixRTC 2.0 calls
|
|
|
|
[MSC4143]: https://github.com/matrix-org/matrix-spec-proposals/pull/4143
|
|
[MSC4195]: https://github.com/matrix-org/matrix-spec-proposals/pull/4195
|
|
[MSC3401]: https://github.com/matrix-org/matrix-spec-proposals/pull/3401
|
|
[MSC4075]: https://github.com/matrix-org/matrix-spec-proposals/pull/4075
|
|
[MSC4354]: https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
|
|
|
Source code:
|
|
|
|
- [Element Call][element-call-github]
|
|
- [lk-jwt-service][lk-jwt-service-github]
|
|
- [LiveKit server][livekit-server-github]
|
|
|
|
[element-call-github]: https://github.com/element-hq/element-call
|
|
[lk-jwt-service-github]: https://github.com/element-hq/lk-jwt-service
|
|
[livekit-server-github]: https://github.com/livekit/livekit
|
|
|
|
Other:
|
|
|
|
- [Matrix VOIP and LiveKit][sspaeth-matrix-voip] - Community member deep dive on current VOIP solutions on Matrix
|
|
|
|
[sspaeth-matrix-voip]: https://sspaeth.de/2026/04/matrix-voip-and-livekit/
|
|
|
|
## Appendix
|
|
|
|
### MatrixRTC calling modes and enabling sticky events {#call-modes}
|
|
|
|
MatrixRTC currently supports 3 calling modes:
|
|
|
|
- **Legacy mode** (deprecated): calls are established by sending state events to a room. The call initiator's SFU hosts the entire call for all remote and local participants.
|
|
- **Compatibility mode*: same as Legacy mode, but utilizes multiple SFUs between federating servers. Clients publish media streams to their own SFUs, and fetch remote streams from remote SFUs. This is the most commonly used mode nowadays.
|
|
- **MatrixRTC 2.0 mode**: also utilizes multiple SFUs, but establishes calls with [sticky events] instead of state events.
|
|
|
|
To support Legacy and Compatibility mode, ensure that the user is allowed to send the relevant state events. Usually, this means promoting them to a power level of 50 or above. Alternatively, set the power level required to send `org.matrix.msc3401.call.member` events to 0.
|
|
|
|
To support MatrixRTC 2.0 mode, sticky events has to be enabled on the Matrix server. In Continuwuity, this is as easy as setting `enable_sticky_events = true` in the config file.
|
|
|
|
### Creating LiveKit tokens via `livekit-cli` {#livekit-cli}
|
|
|
|
To create room tokens directly without going through `lk-jwt-service`, use the [Livekit CLI tool][livekit-cli].
|
|
|
|
<Tabs groupId="livekit">
|
|
<Tab label="Bare Binary">
|
|
|
|
First, download the [release tarball][livekit-cli-releases] and extract it. Then:
|
|
|
|
```sh
|
|
./lk --url https://livekit.example.com \
|
|
--api-key APIUxUnMnSkuFWV \
|
|
--api-secret t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A \
|
|
token create --create --join
|
|
```
|
|
</Tab>
|
|
<Tab label="Docker">
|
|
```sh
|
|
docker run --rm docker.io/livekit/livekit-cli --url https://livekit.example.com \
|
|
--api-key APIUxUnMnSkuFWV \
|
|
--api-secret t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A \
|
|
token create --create --join
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
[livekit-cli]: https://github.com/livekit/livekit-cli
|
|
[livekit-cli-releases]: https://github.com/livekit/livekit-cli
|
|
|
|
### Additional TURN-over-TLS on 443 configuration
|
|
|
|
Most of the time, LiveKit [**does not need TURN**][sspaeth-matrix-voip-turn] to function. However, there are situations where clients may be unable to use nonstandard ports or UDP connections, such as in highly restrictive networks. In such cases, a TURN-over-TLS server on port 443 could relay traffic for the clients.
|
|
|
|
[sspaeth-matrix-voip-turn]: https://sspaeth.de/2026/04/matrix-voip-and-livekit/#turn
|
|
|
|
You can either use LiveKit's built-in TURN server, or integrate LiveKit with [coturn](./turn).
|
|
|
|
<details>
|
|
|
|
<summary>Using LiveKit's built-in TURN server</summary>
|
|
|
|
First, set up LiveKit's built-in TURN server with its own domain - this example will use `livekit-turn.example.com` in our example.
|
|
|
|
```yaml
|
|
## add this to `livekit.yaml` ##
|
|
turn:
|
|
enabled: true
|
|
|
|
# Note: LiveKit will always advertise its TURN-over-TLS port on 443,
|
|
# so further load balancing is needed to route back from port 443
|
|
# on the host to the port being configured here
|
|
tls_port: 5349
|
|
|
|
# Optional: configure an extra UDP port
|
|
# udp_port: 3478
|
|
|
|
relay_range_start: 50300
|
|
relay_range_end: 50400
|
|
|
|
domain: livekit-turn.example.com
|
|
|
|
# replace these with your actual certificate and key files
|
|
cert_file: /path/to/livekit-turn.example.com.crt
|
|
key_file: /path/to/livekit-turn.example.com.key
|
|
```
|
|
|
|
```yaml
|
|
### add these ports to livekit's docker-compose.yml ###
|
|
### if you're using `network_mode: host`, you can skip this part
|
|
ports:
|
|
- "127.0.0.1:5349:5349/tcp"
|
|
- "50300-50400:50300-50400/udp"
|
|
# "3478:3478/udp" # (optional UDP port)
|
|
```
|
|
|
|
Recreate the LiveKit container (with `docker compose up -d livekit`) to apply these changes. Remember to allow the new `50300:50400/udp` ports through your firewall.
|
|
|
|
Then, configure a route from port 443 on the host back to the `livekit-turn.example.com` service on port 5349. To multiplex the service and LiveKit's WebSocket on the same port, use a layer 4 reverse proxy with SNI routing capabilities, such as [Caddy-L4][caddy-l4], on the host system.
|
|
|
|
```
|
|
## in your Caddyfile ##
|
|
{
|
|
servers {
|
|
listener_wrappers {
|
|
|
|
# intercept packets meant for the TURN domain first
|
|
# before forwarding other packets to "normal" HTTP listeners
|
|
layer4 {
|
|
@turn tls sni livekit-turn.example.com
|
|
route @turn {
|
|
# forward packages to LiveKit's TURN-over-TLS port
|
|
proxy 127.0.0.1:5349
|
|
}
|
|
}
|
|
}
|
|
tls
|
|
}
|
|
}
|
|
}
|
|
|
|
# Configuration for the LiveKit modules
|
|
livekit.example.com {
|
|
@lk-jwt-service path /healthz /get_token /sfu/get
|
|
route @lk-jwt-service {
|
|
reverse_proxy 127.0.0.1:8081
|
|
}
|
|
reverse_proxy http://127.0.0.1:7880
|
|
}
|
|
```
|
|
|
|
[caddy-l4]: https://github.com/mholt/caddy-l4
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Using an external TURN server (coturn)</summary>
|
|
|
|
First, make sure coturn's `min-port` and `max-port` do not overlap with LiveKit's port range:
|
|
|
|
```ini
|
|
# in your coturn.conf
|
|
min-port=50201
|
|
max-port=65535
|
|
```
|
|
|
|
Then, generate a long random TURN secret for LiveKit, and add it to your coturn config under the `static-auth-secret` option. coturn allows multiple secrets in its configuration, so set a different one for LiveKit to use.
|
|
|
|
After that, refer to the following [TURN-over-TLS on 443 instructions](./turn#turn-over-tls-on-443) to set up coturn with TLS, as well as multiplexing with LiveKit's WebSocket on port 443.
|
|
|
|
Then configure LiveKit, making sure to replace `COTURN_SECRET` with the one you generated:
|
|
|
|
```yaml
|
|
### in your livekit.yaml ###
|
|
rtc:
|
|
# ... other configs here ...
|
|
stun_servers:
|
|
- coturn.example.com
|
|
turn_servers:
|
|
- host: coturn.example.com
|
|
port: 443
|
|
protocol: tls
|
|
secret: "COTURN_SECRET"
|
|
```
|
|
|
|
Restart LiveKit, coturn, and Caddy-L4 to apply these changes.
|
|
|
|
</details>
|
|
|
|
Once the services are configured, run the Testing steps again to check that TURN-over-TLS on 443 is working. There should now be a green tick in the [LiveKit connection test page][livekit-connection-test] showing "Can connect to TURN" to confirm this is set up successfully.
|