MatrixRTC back-end deployment using Docker and Traefik.
Find a file
2025-11-25 12:02:49 +02:00
data/livekit Initial commit. 2025-09-08 19:48:26 +03:00
.env Initial commit. 2025-09-08 19:48:26 +03:00
docker-compose.yaml Initial commit. 2025-09-08 19:48:26 +03:00
LICENSE Initial commit. 2025-09-08 19:48:26 +03:00
README.md Minor edit to the README. 2025-11-25 12:02:49 +02:00

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