Element Call als Add-on für Matrix Synapse (Docker)

Version: 25.05.20

In dem folgenden Tutorial wollen wir als Ergänzung zu unserem Matrix-Synapse-Server (Docker) Element Call hinzufügen – ebenfalls als Docker-Container.

Seit Anfang 2025 funktionieren Anrufe über ElementX nicht mehr automatisch über Jitsi oder Coturn wie bei Element Classic, sondern das ElementCall-Backend (LiveKit und JWT) für ElementX muss selbst gehostet werden.

Da ElementClassic nicht mehr weiterentwickelt wird, müssen alle User demnächst auf ElementX wechseln. Für Element Call (über LiveKit und JWT) sprechen dabei aber viele gute Eigenschaften:

✅ Dezentralisiert & Föderiert – Keine zentrale Instanz; funktioniert über verschiedene Matrix-Homeserver hinweg.
✅ Ende-zu-Ende-Verschlüsselt – Sichere und private Gespräche.
✅ Eigenständig & im Widget-Modus – Als eigenständige App nutzbar oder in Matrix-Clients einbettbar.
✅ WebRTC-basiert – Keine zusätzliche Software erforderlich.
✅ Skalierbar mit LiveKit – Unterstützt große Meetings über SFU (MSC4195: MatrixRTC mit LiveKit-Backend).
✅ Hand heben – Teilnehmer können signalisieren, wenn sie sprechen möchten, um den Gesprächsfluss zu organisieren.
✅ Emoji-Reaktionen – Nutzer können mit Emojis 👍️ 🎉 👏 🤘 reagieren und so für mehr Engagement und Interaktivität sorgen.

In unserem Tutorial werden wir LiveKit und den JWT-Service installieren, damit ElementCall funktioniert:

LiveKit und der JWT Service spielen zentrale Rollen in der Erweiterung von Element Call für große und skalierbare Meetings:


🔊 LiveKit – für skalierbare Sprach-/Videoanrufe

LiveKit ist ein SFU (Selective Forwarding Unit)-basierter Medienserver, der die Verarbeitung und Verteilung von Audio- und Videostreams übernimmt. Er wird benötigt, wenn viele Teilnehmer gleichzeitig an einem Meeting teilnehmen sollen – also über das hinaus, was Peer-to-Peer-Verbindungen (wie bei kleinen Calls) leisten können.
Warum notwendig?

  • Ermöglicht große Meetings mit hoher Qualität.
  • Entlastet Clients, da Streams zentral weiterverteilt werden.
🔐 JWT Service – für sichere Authentifizierung

Der JWT (JSON Web Token) Service stellt signierte Tokens aus, die Benutzer gegenüber LiveKit authentifizieren. Nur Clients mit gültigem Token dürfen einem Call über LiveKit beitreten.

Warum ist dieser notwendig?

  • Verhindert unautorisierten Zugriff auf LiveKit.
  • Ermöglicht eine sichere und kontrollierte Teilnahme an Anrufen.

Kurz gesagt:
🔧 LiveKit macht große, stabile Meetings möglich.
🔒 JWT Service sorgt dafür, dass nur berechtigte Nutzer daran teilnehmen dürfen.

Beide Komponenten sind unerlässlich für den skalierbaren und sicheren Betrieb von Element Call in einer produktiven Umgebung.


🛠 Voraussetzungen für diese Anleitung:


– Matrix Synapse ist nach diesem Tutorial bereits vollständig eingerichtet: Tutorial Deutsch
– sehr gute Linux und Terminal Kenntnisse

Bei dem Tutorial zu Matrix Synapse wurden schon einige Vorbereitungen für Element Call getroffen.
Anbei noch einmal die wichtigsten Vorbereitungen zusammengefasst:

⚠️ In der Firewall bei dem VPS-Anbieter oder in der UFW bei Linux, falls diese genutzt wird, wurden folgende Ports freigegeben:

TCP: 7881-7882 und UDP 50100 – 50200

⚠️ Das Docker-Netzwerk „matrixnetwork“ wurde eingerichtet, damit die Docker Container (Synapse, LiveKit und JWT) in einem Netzwerk sind:

In der „homeserver.yaml“ Datei von Synapse müssen ebenfalls schon die Vorbereitungen für ElementCall eingetragen sein:

Und die Docker-Container Datei von Synapse muss dem Docker-Netzwerk hinzugefügt worden sein:

Wenn das Tutorial befolgt worden ist, dann ist bereits alles richtig vorbereitet worden.


🔧 Installation von ElementCall (LiveKit und JWT)

Wir starten nun mit der Einrichtung von ElementCall und loggen uns auf dem Server ein:

Zuerst sorgen wir dafür das der Server auf dem neusten Stand ist mit folgendem Befehl:

Nachdem alles auf den neusten Stand gebracht ist, erstellen wir ein Verzeichnis in unserem Docker-Projektordner (beispielsweise im /home/-Ordner):

Wir wechseln in das Projektverzeichnis mit:

Damit Livekit und der JWT Service verschlüsselt miteinander kommunizieren können, legen wir zwei zufällige Schlüsselpaare an, die wir uns notieren um diese später eintragen zu können. Dazu benutzen wir folgenden Befehl:

Nun richten wir die docker-compose.yml Datei im Ordner /elementcall/ ein:

Die Docker-Compose enthält folgenden Inhalt, wobei einige Anpassungen vorzunehmen sind:

Folgende Anpassungen sind in der Datei vorzunehmen:

  • matrixnetwork ipv4 Adressen: sind dem „Matrixnetwork“ (siehe oben, Docker Netzwerk) anzupassen, die IPs der einzelnen Container werden hier selbständig eingegeben (fortlaufende Reihenfolge für Synapse, LiveKit und JWT – .13 .14 .15 .16 usw)
  • LIVEKIT_URL: hier kommt die Subdomain rein, unter der der LivekitServer erreichbar sein wird. Diese Subdomain muss später noch angelegt werden (siehe unten)
  • LIVEKIT_KEY und LIVEKIT_SECRET: Hier kommen die zwei oben zufällig generierten Codes rein
  • LIVEKIT_LOCAL_HOMESERVERS: hier kommt die Hauptdomain eures VPS Servers rein also keine Subdomain sondern die „domain.com“

Ein kurzer Hinweis zu der Umgebungsvariable:

  • LIVEKIT_LOCAL_HOMESERVERS=domain.com

Diese Variable gehört zu einer noch in Entwicklung befindlichen LiveKit-Funktion. Sie legt fest, welche Homeserver neue Anrufe starten dürfen. Künftig können damit nur Nutzer deines eigenen Homeservers Calls initiieren; föderierte Nutzer dürfen weiterhin beitreten, aber keine neuen Gespräche beginnen.

Praktisch ist das vor allem bei öffentlichen Diensten mit Zugangskontrolle. Noch hat die Einstellung keine Wirkung, kann aber bereits gesetzt werden, um vorbereitet zu sein.

Möchtest du mehreren Homeservern erlauben, neue Anrufe zu starten, gib sie einfach durch Komma getrennt an:

  • LIVEKIT_LOCAL_HOMESERVERS=domain.com,example.com

Als nächstes legen wir die LiveKit-Konfiguration an:

In die Datei kommt der folgende Inhalt rein (nano benutzen als Editor):

Zu den Variablen:

  • includes: ist die IP-Adresse eures VPS (/32 mit angeben!)
  • keys: sind die Keys oben aus der docker-compose.yml (zuerst der LIVEKIT_KEY und dann LIVEKIT_SECRET)

Als nächstes wird der DNS-Eintrag für ElementCall bei dem VPS anbieter gesetzt:

Ein A-Record ist dabei vollkommen ausreichend – AAAA wird nicht benötigt:

rtc.matrix.domain.com    7200    IN    A    111.150.60.108

Nächster Schritt: Mit dem NGINX Proxy Manager (NPM) die Weiterleitungen einrichten

Wir legen die Domain an, die wir bereits in die docker-compose.yml eingetragen haben und für die auch bereits ein A-Record bei unserem VPS-Anbieter besteht (LIVEKIT_URL):

Die IP-Adresse die wir hier eintragen, ist dabei die interne Docker-IP (matrixnetwork) für den JWT Service aus der docker-compose.yml.

Wir müssen aber unter Advanced noch eine „Custom NGINX Proxy Configuration“ eingeben:

Auch hier wieder zur Erklärung: Die obere IP Adresse mit der 14 am Ende verweist auf den internen Docker Container JWT und die IP Adresse mit der 15 am Ende verweist auf die LiveKit IP Adresse, ebenfalls aus der docker-compose.yml.

Wir speichern den Eintrag im NPM Manager.


👉 Well-Known-Konfiguration

Ein essenzieller Bestandteil der Matrix-Konfiguration ist der .well-known-Eintrag. Er teilt Clients wie ElementX mit, wo sich dein Homeserver befindet und wie das LiveKit-Backend für MatrixRTC (Element Call) erreichbar ist.

🔧 Entscheidend ist, auf welcher Domain der Eintrag verfügbar ist – diese muss mit dem server_name aus der homeserver.yaml übereinstimmen.

Zusätzlich relevant ist /.well-known/matrix/server, der für die Föderation benötigt wird. Dieser verweist andere Server auf deinen Synapse-Endpunkt – vor allem wichtig bei Delegation oder wenn Synapse nicht direkt unter dem server_name läuft.

📌 In der Regel wird .well-known/matrix/client bei der Synapse-Installation automatisch erstellt. Für Element Call erweitern wir diesen nur. Dennoch gehen wir hier die gesamte Konfiguration durch, um bestehende Einträge korrekt anpassen zu können.

🔍 Domain-Zuordnung für .well-known:

server_name: matrix.domain.com
.well-known gehört auf https://matrix.domain.com.

server_name: domain.com
.well-known muss unter https://domain.com erreichbar sein.

Wir richten den .well-known Eintrag wieder unter „Advanced“ im NPM Manager ein:

Wir haben alle Arbeiten erfolgreich abgeschlossen.

Nun schauen wir, dass wir wieder in das Projektverzeichnis gehen (/home/elementcall) und den Container starten:

Das Ergebnis können wir mit „docker ps“ in der Kommandozeile abfragen. Wir sollten sehen, dass die Container laufen:


Was haben wir in diesem Tutorial erreicht?

Installation von ElementCall: LiveKit und JWT

  • Matrix Synapse über die Zusatzfunktionen mit ElementCall verbunden
  • Subdomains eingerichtet (rtc.matrix.domain.com)
  • NGINX Proxy Manager richtig konfiguriert
  • .well-known Eintrag bei der Domain richtig gesetzt

Viel Spaß beim sicheren telefonieren (mit Video) über ElementCall (LiveKit+JWT) und ElementX !

Das offizielle Projekt und weitere Anleitungen findet man unter Github: https://github.com/element-hq/element-call


bc1q8dxp9mlt3mkvaklu2vn8j6jteqyv53kschc90v

Lightning: itsc@strike.me

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert