Jitsi Meet is a self-hosted Free and Open-Source Software (FOSS) video conferencing solution. During the recent COVID-19 pandemic, the project became quite popular, and many companies decided to host their own Jitsi instance.
At cynkra, while we have been running our own Jitsi instance quite happily for some months, there was a slightly challenging task coming up: hosting a virtual meeting for approximately 100 participants.
When browsing the load capabilities of a single Jitsi instance, we found that the stock setup begins to experience some challenges at around 35 people and fails at around 70 people. The limiting factor appears to be the “videobridge”. One solution is to add a second videobridge to the Jitsi instance. Jitsi can then distribute the load and should be able to host more than 100 people in a meeting.
The best approach is to deploy the second videobridge on a new instance to avoid running into CPU limitations on the main machine. While there is a guide in the Jitsi Wiki and a video that explains how to do it, many people still struggle (1, 2) to get this set up successfully.
Hence, we thought it would be valuable to take another, hopefully simple and understandable stab at explaining this task to the community.
Load-balancing Jitsi Meet
In the following, we will denote the main machine on which Jitsi runs, as MAIN. The second machine, which will only host a standalone videobridge, will be named BRIDGE.
The first step is to create a working installation on MAIN, following the official docker guide from the Jitsi developers. There is no need to use Docker. An installation on the host system will also work.
At this point, we assume that you already have installed Jitsi with SSL support at a fictitious domain.
To be able to connect to the XMPP server (managed by
prosody) on MAIN from BRIDGE (details in point 4 below), port 5222 needs to be exported to the public. This requires adding
ports: - "5222:5222"
docker-compose.ymland ensuring that the port is opened in the firewall (
ufw allow 5222).
On BRIDGE, start with the same
docker-compose.yml, remove all services besides
jvb. The videobridge will later connect to all services on MAIN.
Make sure that
.envare the same as on MAIN, otherwise the authentication will fail.
On BRIDGE in
docker-compose upand observe what happens. The videobridge should successfully connect to
<DOMAIN>. On MAIN, in
docker logs jitsi_jicofo_1, an entry should appear denoting that a new videobridge was successfully connected.
It looks like
Jicofo 2020-10-23 19:01:52.173 INFO:  org.jitsi.jicofo.bridge.BridgeSelector.log() Added new videobridge: Bridge[jid=jvbbrewery@internal-muc.<DOMAIN>/d789de303e9b, relayId=null, region=null, stress=0.00]
If you have another videobridge running on MAIN, you should see that the identifier of the new videobridge (here
d789de303e9b) is different to your main videobridge identifier. On BRIDGE, the logs should show something like
INFO: Joined MUC: jvbbrewery@internal-muc.<DOMAIN> INFO: Performed a successful health check in PT0S. Sticky failure: false
To test that the external videobridge is active, one can disable the main videobridge (
docker stop jitsi_jvb_1) and try to enable the camera in a new meeting.
Troubleshooting and Tips
If you see something like
SASLError using SCRAM-SHA-1: not-authorized, this indicates that the
JVB_AUTH_USERon BRIDGE are incorrect.
If you change something in
.envof MAIN, you need to delete all config folders before running
docker-compose upagain. Otherwise changes won’t be picked up even when force destroying the containers.
Do not run
gen-passwords.shmultiple times as
JVB_AUTH_PASSWORDand BRIDGE will not be able to connect anymore.
Unrelated to the content above: if you want to create a user manually for your instance, the following command might be helpful:
docker exec jitsi_prosody_1 prosodyctl --config /config/prosody.cfg.lua register <USER> <DOMAIN> "<PASSWORD>"
More postsEFS vs. NFS for RStudio on Kubernetes (AWS): Configuration and considerations
Patrick SchratzAccessing Google's API via OAuth2
Patrick SchratzData Scientist (80-100%)
cynkra teamseasonal 1.9: Accessing composite output
Christoph SaxGoogle Season of Docs with R: useR! Information Board
Ben UbahRunning old versions of TeXlive with tinytex
Kirill Müllertsbox 0.3.1: extended functionality
Christoph SaxCelebrating one-year anniversary as RStudio Full Service Certified Partner
Cosima Meyer, Patrick SchratzDeprecating a pkgdown site served via GitHub Pages
Patrick Schratz, Kirill Müllergfortran support for R on macOS
Patrick SchratzSeasonal Adjustment of Multiple Series
Christoph SaxDynamic build matrix in GitHub Actions
Kirill MüllerSetting up a load-balanced Jitsi Meet instance
Patrick SchratzDevOps Expert (f/m/d, 60-100%)
cynkra teamMaintaining multiple identities with Git
Kirill MüllerRelational data models in R
Angel D'az, Kirill Müllertempdisagg: converting quarterly time series to daily
Christoph Saxtsbox 0.2: supporting additional time series classes
Christoph SaxDevOps System Engineer (40-60%)
cynkra teamIntroducing dm: easy juggling of tables and relations
Balthasar Sagertsbox 0.1: class-agnostic time series
Christoph SaxData Scientist/Engineer (40-100%)
cynkra teamTime series of the world, unite!
Christoph SaxDone “Establishing DBI”!?