| data/livekit | ||
| .env | ||
| docker-compose.yaml | ||
| LICENSE | ||
| README.md | ||
MatrixRTC Back-End for Synapse with Docker Compose and Traefik
Introduction
To enable audio and video calls for Matrix clients such as Element X which implement the current Matrix specification, Matrix servers must provide a MatrixRTC back-end, comprised of LiveKit Server and MatrixRTC Authorization Service instances.
While a number of guides explaining how to deploy a Synapse Matrix server instance using Docker Compose and Traefik may be found on the internet, instructions for deploying a MatrixRTC back-end using Traefik as a reverse proxy appear to have been so far unavailable as of the time of writing. This short guide is intended to fill that gap.
This repository contains a Docker Compose file and associated configuration files enabling the deployment of a MatrixRTC back-end using Traefik as a reverse proxy. Cloning the repository (or copying the contents of the configuration files) onto a qualified server and performing the configuration described below should result in a functional MatrixRTC back-end deployment.
Should you find an error in these instructions or encounter any problems and require assistance, feel free to contact me.
Installation
Requirements
These instructions assume that a working Synapse instance has been deployed using Docker Compose and Traefik on the the target server, which is assumed to be running a GNU/Linux operating system e.g. Debian.
The instructions were tested with the following major software versions.
| Software | Version |
|---|---|
| Debian | 13 (Trixie) |
| Docker Compose | 2 |
| Traefik | 3 |
DNS Records
In the domain name registrar's DNS admin panel, create a CNAME record for the MatrixRTC back-end for the target domain name.
Example:
| Name | Record |
|---|---|
| matrix-rtc | example.com |
Synapse Configuration
As explained in the official documentation, add the following content to Synapse's homeserver.yaml configuration file.
# Configuration to enable new style calls using self-hosted MatrixRTC back-end.
# https://github.com/element-hq/element-call/blob/livekit/docs/self-hosting.md#a-matrix-homeserver
experimental_features:
# MSC3266: Room summary API. Used for knocking over federation
msc3266_enabled: true
# MSC4222 needed for syncv2 state_after. This allow clients to
# correctly track the state of the room.
msc4222_enabled: true
# The maximum allowed duration by which sent events can be delayed, as
# per MSC4140.
max_event_delay_duration: 24h
rc_message:
# This needs to match at least e2ee key sharing frequency plus a bit of headroom
# Note key sharing events are bursty
per_second: 0.5
burst_count: 30
rc_delayed_event_mgmt:
# This needs to match at least the heart-beat frequency plus a bit of headroom
# Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
per_second: 1
burst_count: 20
As explained in the official documentation, add a section in Synapse's .well-known/matrix/client config file, adjusting the value of the livekit_service_url parameter to reflect the target domain name.
Sample contents:
{
"m.homeserver": {
"base_url": "https://example.com"
},
"org.matrix.msc4143.rtc_foci":[
{
"type":"livekit",
"livekit_service_url":"https://matrix-rtc.example.com/livekit/jwt"
}
]
}
Restart the Docker containers comprising the Synapse instance. For example:
cd /opt/containers/matrix
docker compose up -d
Important: If using Element Desktop as the Matrix client, it may be necessary to delete the contents of Element's local configuration directory, so that the configuration specified in the .well-known/matrix/client config file will be applied. For example:
rm -rf ~/.config/Element
MatrixRTC Back-End
This repository contains the following files:
| File | Description |
|---|---|
| docker-compose.yaml | Docker Compose file with Traefik labels facilitating the deployment of the MatrixRTC back-end. |
| .env | Contains the LiveKit secret. |
| data/livekit/config.yaml | A sample LiveKit config file. |
Either clone the repository into a dedicated folder on the target server as documented below or simply add the contents of the configuration files to the existing configuration for the Synapse server instance. An advantage to taking the latter approach is that whenever the Docker containers for Synapse and the MatrixRTC back-end are updated and restarted, they will be updated/restarted together.
Cloning the repository into the target directory on the server may be accomplished thus:
cd /opt/containers
git clone https://forge.avontech.net/kstro1/matrixrtc-docker-traefik matrix-rtc
Now change into the target directory. For example:
cd matrix-rtc
Replace the dummy value "example.com" with the intended domain name in docker-compose.yaml.
sed -i 's/example.com/yourdomain.com/g' docker-compose.yaml
Applying any suitable method, generate a secure random string to use as the LiveKit secret. For example:
livekit_secret=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 40)
Replace the dummy value "insert_livekit_secret" with the value generated above in the .env and data/livekit/config.yaml config files:
sed -i "s/insert_livekit_secret/$livekit_secret/g" .env
sed -i "s/insert_livekit_secret/$livekit_secret/g" ./data/livekit/config.yaml
Inspect docker-compose.yaml to verify whether anything else needs to be adjusted for compatibility with the configuration of the deployed Traefik instance. Verify that the specified network (lines 31, 57 & 64) is the same as that used by Traefik. Also check the value of the certresolver setting (lines 23 & 49).
Pull the target images and build and run the Docker containers:
docker compose up -d
Logs may be inspected as follows.
docker compose logs
docker compose logs | grep element-call-livekit
docker compose logs | grep element-call-jwt
Testing
The MatrixRTC back-end may be tested using the rather convenient testmatrix Python package: https://codeberg.org/spaetz/testmatrix
Assuming that Python 3 is installed on your workstation, it may be installed as follows:
python3 -m venv ~/.venv/testmatrix
source ~/.venv/testmatrix/bin/activate
pip install testmatrix
To perform a short test:
testmatrix example.com
To perform a full test, provide the username and API access token of a user authorised to use the server's SFU instance (ordinarily any user will do):
testmatrix example.com -u <username> -t <access_token>
Note: The API access token may be obtained by executing the following command:
curl -XPOST -d \
'{"type":"m.login.password", "user":"<username>", "password":"<password>"}' \
"https://synapse.example.com/_matrix/client/r0/login"
Troubleshooting
General
At the time of writing, it is possible to configure a homeserver to use the MatrixRTC back-end instance provided by Element by setting the livekit_service_url parameter in Synapse's .well-known/matrix/client config file to https://jwt.call.element.io. This may be useful for testing and debugging.
Firewall
If using the UFW firewall, run the following command to verify that UFW is not blocking a connection, causing a call to fail.
journalctl --since "2025-09-07 09:00:00" | grep "UFW BLOCK"
Debug Console
The debug console in Element Desktop may be opened by pressing CTRL+SHIFT+I and switching to the console tab.
Software Updates
Keeping the MatrixRTC instance up to date with the latest software may be accomplished by pulling the latest images listed in the table below for the corresponding tags.
| Image | Tag |
|---|---|
| ghcr.io/element-hq/lk-jwt-service | latest |
| livekit/livekit-server | latest |
To perform a manual update, pulling the latest container image for each tag and rebuilding any out of date containers, execute the following commands:
docker compose pull
docker compose up -d
Obsolete images may be removed as follows:
docker image prune