Element Calls
Table of Contents
Installation for Element X
Install LiveKit
docker pull livekit/generatedocker run --rm -it -v$PWD:/output livekit/generate-> LiveKit Server Only Then:
- edit compose file - remove build-on caddy
- configure to use external STUN & TURN servers (as per config example)
Setup Caddy
-1. Configure DNS to point to the server
livekit.example.com { reverse_proxy localhost:7880}Install JWT
2025-04-28
services:
jwt-service: image: ghcr.io/element-hq/lk-jwt-service:latest container_name: jwt restart: unless-stopped environment: - LIVEKIT_URL=wss://livekit.example.com # goes from livekit generate output - LIVEKIT_SECRET=<your-livekit-secret> # Put in the livekit secret defined within the livekit.yaml - LIVEKIT_KEY=<your-livekit-key> # Put in the livekit key defined within the livekit.yaml - LIVEKIT_LOCAL_HOMESERVERS=example.com # Set this to your homeserver namejwt.example.com { log tls /etc/ssl/example_com.crt /etc/ssl/example_com.key
reverse_proxy jwt:8080}Change server
2025-04-29
-0. Add settings to Synapse server: https://github.com/element-hq/element-call/blob/livekit/docs/self-hosting.md#a-matrix-homeserver
Add the following to homeserver.yaml
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-1. Add .well-known/matrix/client to Caddy: https://github.com/element-hq/element-call/blob/livekit/docs/self-hosting.md#matrixrtc-backend-announcement
@well_known_client { path /.well-known/matrix/client } handle @well_known_client { respond `{ "m.homeserver": {"base_url":"https://matrix.example.com:443"}, "org.matrix.msc2965.authentication": { "issuer": "https://auth.example.com/", "account": "https://auth.example.com/account"}, "im.vector.riot.jitsi": {"preferredDomain":"jitsi.example.com"}, "org.matrix.msc4143.rtc_foci": [ {"type": "livekit", "livekit_service_url": "https://jwt.example.com/"}, {"type": "livekit", "livekit_service_url": "https://livekit.example.com/"}, {"type": "nextgen_new_foci_type", "props_for_nextgen_foci": "val"} ] }` }Pre-ready-to-use setup
As of 2024-12-05 updated Readme.md presents a much better docker-compose.yml (commit) Also - there is a description on how to build and use on FreeBSD.
And there is an issue with discussion on it: https://github.com/element-hq/element-meta/issues/2371
Refs:
A very useful issue with hints and optimizations.
SW install
# adding swap (to avoid build time issues with memory)sudo swapon --showfree --giga -hsudo fallocate -l 8G /swapfilesudo chmod 600 /swapfilesudo mkswap /swapfilesudo swapon /swapfilesudo swapon --showecho "/swapfile none swap sw 0 0" >> /etc/fstab
# installing dockerwget -O - https://raw.githubusercontent.com/alexander-potemkin/quickies/main/docker_ubuntu.sh | sudo bashapt-get install docker-compose-plugin
# caddysudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curlcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpgcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.listsudo apt updatesudo apt install caddy
# Synapse servermkdir synapse-server && cd synapse-serverwget https://raw.githubusercontent.com/element-hq/synapse/develop/contrib/docker/docker-compose.ymlvi docker-compose.yml # remove postgresql & traefik labelsdocker compose run --rm -e SYNAPSE_SERVER_NAME=synapse.example.com -e SYNAPSE_REPORT_STATS=no synapse generate# docker compose down --remove-orphans # if missed removing external db earliercat >> files/homeserver.yaml << EOTenable_registration: trueregistration_requires_token: falseenable_registration_without_verification: trueallow_guest_access: trueexperimental_features: msc3266_enabled: trueEOT
# nodejs & yarncurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - &&\sudo apt-get install -y nodejscorepack enableyarn
# matrix-js-sdkgit clone https://github.com/matrix-org/matrix-js-sdk.gitcd matrix-js-sdkyarnyarn link
# element callgit clone https://github.com/element-hq/element-call.gitcd element-callyarnyarn link matrix-js-sdkConfig
- setup DNS names for web front-end
- setup caddy
vi /etc/caddy/Caddyfile:
# staticcall.example.com { file_server root * /var/www/ try_files {path} /{path} /index.html}
jwt.example.com { reverse_proxy localhost:8881}
synapse.example.com { reverse_proxy localhost:8008}
synapse.example.com:8448 { reverse_proxy localhost:8008}
livekit.example.com { reverse_proxy localhost:7880}vi /var/www/config.json (ConfigOptions.ts is considered to be a documentation):
{ "default_server_config": { "m.homeserver": { "base_url": "https://synapse.example.com", "server_name": "synapse.example.com" } }, "livekit": { "livekit_service_url": "https://jwt.example.com" }, "eula": "https://example.com/404"}Build and place web app:
mkdir /var/wwwcd element-callyarn buildcp -R dist/* /var/www/cp -R dist/.* /var/www/cd /var/www/cp config.sample.json config.jsonvi config.json # take file content from aboveservice caddy restartvi backend-docker-compose.yml # adjust LIVEKIT_URL=ws://livekit.example.com:7880docker compose -f backend-docker-compose.yml up -dSecuring
Synapse server
Matrix level outside access can be prohibited using the following directives at homeserver.yaml:
enable_registration: falseregistration_requires_token: trueenable_registration_without_verification: trueallow_guest_access: falseexperimental_features: msc3266_enabled: trueUsers shall be added with the following command then:
docker exec -it synapse-server-synapse-1 register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml --no-admin -u guest -p <guest-password>LiveKit
Change (to pwgen 89’s output):
LIVEKIT_KEY&LIVEKIT_SECRETatbackend-docker-compose.yaml- match them with
keysatbackend/livekit.yaml(LIVEKIT_KEY:LIVEKIT_SECRETformat) docker ... down&&docker up -d-restartdoesn’t work for some reason.
Redis
Adjust ports section in backend-docker-compose.yaml to look like 127.0.0.1:6379:6379 (ref)
ToDo
- process information from that ticket and that ticket and place on Troubleshooting
- Place as a todo item - domains to direct to the server Assembling my config variables:
- Synapse server:
-> ‘synapse.example.com’ - Element call server:
-> ‘call.example.com’ - LiveKit server:
-> ‘livekit.example.com’ - JWT server:
-> ‘jwt.example.com’
Troubleshooting
- try federation tester against Synapse server
- collect logs from web app as described on that issue
Known limitations
- call.mydomain.com integration in messengers missing - here is an issue.
Basura (remove after redone)
Synapse server config:
- enable_notifs => false
- registration_shared_secret: "
" - allow_guest_access: false
- experimental_features: msc3266_enabled: true
Installed Synapse server with registration enabled and - before starting to use the server - changed the server name to a full DNS name.