by Sam Hadow
In this blog post I’ll explain how to setup element call using synapse as a matrix homeserver. This blog post assumes you already followed this one.
in the homeserver.yaml in your synapse homeserver add the following:
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.2Hz
per_second: 1
burst_count: 20
run:
podman run --rm livekit/livekit-server:latest generate-keys
And write down the API key and API secret.
Don’t forget to replace YOUR_PUBLIC_IP, YOUR_API_KEY and YOUR_API_SECRET
mkdir -p /home/data/podman/element-call
in /home/data/podman/element-call/config-livekit.yaml:
port: 7880
bind_addresses:
- "0.0.0.0"
rtc:
tcp_port: 7881
port_range_start: 50100
port_range_end: 50200
node_ip: YOUR_PUBLIC_IP
room:
auto_create: false
logging:
level: info
turn:
enabled: false
keys:
YOUR_API_KEY: YOUR_API_SECRET
For the containers replace matrixrtc.hadow.fr, hadow.fr and synapse.hadow.fr with your own domains.
podman run -d \
--pod=synapse \
--name=element-call-jwt \
--restart=unless-stopped \
-e LIVEKIT_JWT_BIND=:8080 \
-e LIVEKIT_URL=wss://matrixrtc.hadow.fr/livekit/sfu \
-e LIVEKIT_KEY=YOUR_API_KEY \
-e LIVEKIT_SECRET=YOUR_API_SECRET \
-e LIVEKIT_FULL_ACCESS_HOMESERVERS=hadow.fr \
-e MATRIX_HOMESERVER_URL=https://synapse.hadow.fr \
ghcr.io/element-hq/lk-jwt-service:latest
podman run -d \
--pod=synapse \
--name=element-call-livekit \
--restart=unless-stopped \
-v /home/data/podman/element-call/config-livekit.yaml:/etc/livekit.yaml:ro,Z \
docker.io/livekit/livekit-server:latest \
--config /etc/livekit.yaml
You can now regenerate the files for the systemd services:
cd ~/.config/systemd/user/
podman generate systemd --restart-policy=on-failure --files --new --name synapse
systemctl --user daemon-reload
systemctl --user restart pod-synapse.service
Then complete in pod-synapse.service with the ports:
-p 8008:8008 \
-p 7880:7880 \
-p 7881:7881 \
-p 50100-50200:50100-50200/udp \
-p 8070:8080 \
-m=2048m
Don’t forget to open the UDP range 50100-50200 and the TCP port 7881 in your firewall. For example with nftables:
#element call
tcp dport 7881 accept
udp dport 50100-50200 accept
In a nginx configuration file (for example in /etc/nginx/sites-available/matrixrtc.conf):
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name matrixrtc.hadow.fr;
ssl_certificate /etc/letsencrypt/live/hadow.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hadow.fr/privkey.pem;
location ^~ /livekit/jwt/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8070/;
}
location ^~ /livekit/sfu/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffering off;
proxy_set_header Accept-Encoding gzip;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:7880/;
}
}
In your well known in /etc/nginx/sites-available/http.conf modify the snippet with the following:
location /.well-known/matrix/client {
return 200 '{"m.homeserver": {"base_url": "https://synapse.hadow.fr"},"m.identity_server": {"base_url": "https://vector.im"},"org.matrix.msc4143.rtc_foci": [{"type": "livekit","livekit_service_url": "https://matrixrtc.hadow.fr/livekit/jwt"}]}';
add_header Content-Type application/json;
add_header "Access-Control-Allow-Origin" *;
}