Installing Jitsi and Jibri on Same Machine

This post is heavily inspired from this community post by However, the original installation document is based on typical split Jitsi on one VM and Jibri on seperate VM. 

A little reworked version is deployed and tested for several client based with no performance issue- this post covers a single VM with Jitsi Videobridge and Jibri Reocording system.


  • Works only on Ubuntu 16 Distribution
  • Only following DNS entries are needed to be available:
    • ->
  • update /etc/hosts file as following:

Part-1: Setup Jitsi Meet on the server

You will need to login to the server you created in step 1. For this, on my Windows laptop, I use PuTTy. Login with initial password and change it to your own.

Update server:

apt update && apt upgrade -y

Update hostname:

hostnamectl set-hostname

Install NGINX

If Jitsi Meet gets installed on a fresh server, it will install it’s own webserver (Jetty) in the process. From what I find in the forums, I prefer to go with NGINX, so let’s install that first. In the terminal:

apt install nginx -y

Hint: We do NOT have to configure anything for NGINX: the jitsi-installer will take care of that!

apt install -y apt-transport-https

Install Jitsi Meet

First we need to add the repositories where our server should retrieve the Jitsi Meet packages, in the terminal:

echo 'deb stable/' >> /etc/apt/sources.list.d/jitsi-stable.list
wget -qO - | sudo apt-key add -
apt update && apt install jitsi-meet -y

During installation we can expect 2 questions:

Domain – Here I enter the full domain:

Certificate – Leave this option at the default to install Let’s Encrypt certificates afterwards. Generate Let’s Encrypt certificates for our domain 

Currently, the build is broken and at the end of the process it shows error message:
Unable to find deploy-hook command /etc/letsencrypt/renewal-hooks/deploy/ in the PATH.
(PATH is /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)

As a workaround we can do following:

mkdir -p /etc/letsencrypt/renewal-hooks/deploy/
touch /etc/letsencrypt/renewal-hooks/deploy/
chmod +x /etc/letsencrypt/renewal-hooks/deploy/

Execute the Let’s Encrypt script:


The script will ask for your email address where Let’s Encrypt will send information in case of expiration -date or such.

At this point you should have a working Jitsi Meet server!

Open a browser and enter the domain of your Jitsi Meet, I open and get greeted by the welcome screen. Here I create a new meeting ‘test’ and open a conference (make sure to ALLOW the browser to use microphone and camera). I always open an incognito window and open the same meeting I initiated already: 7test so there should now be 2 participants in the call. Opening a 3rd browser to that same meeting ensures that we know if Jitsi switches from peer2peer mode to videobridge mode. When 3 participants are showing in the call, we know all is well so far.

Tweaking and tuning

Tuning A) Prosody portmanager error

service prosody status

(type ‘q’ to quit the output console)

● prosody.service - Prosody XMPP Server
Loaded: loaded (/lib/systemd/system/prosody.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-04-15 19:39:18 CEST; 32min ago
Docs: 5
Main PID: 16994 (lua5.2)
Tasks: 1 (limit: 2296)
Memory: 18.5M
CGroup: /system.slice/prosody.service
└─16994 lua5.2 /usr/bin/prosody

Apr 15 19:39:18 34 systemd[1]: Started Prosody XMPP Server.
Apr 15 19:39:19 34 prosody[16994]: portmanager: Error binding encrypted port for https: No certificate
Apr 15 19:39:19 34 prosody[16994]: portmanager: Error binding encrypted port for https: No certificate

The portmanager error basically is harmles and can be ignored. But we can also fix this.

nano /etc/prosody/conf.avail/

Before the first Virtualhost entry, insert following:

-- we are going to be proxying the BOSH connection anyway, so there is no need to be listening for BOSH over HTTPS
https_ports = { }

Save the changes and restart prosody, all should be happy now: 

service prosody restart
service prosody status

Tuning B) Improving over-all performance by sacrificing audio-indicator animation

nano /etc/jitsi/meet/

Find the audio-section and set:

disableAudioLevels: true,

With this setting, you loose the visually appealing sound level indicators/animations in the call, but this also removes a lot of overhead and screen-rewriting. On this rather poor-dimensioned server, this brings a noticable performance gain.

Found here: [Customizing jitsi — viewer only — bandwidth — usecase 56]

Tuning C) Video resolution and bitrate

Jitsi Meet sends 720p resolutions with 30 fps (at least afaik).
Google’s recommendations are:
Resolution: 1280×720 @ 30 fps
Video Bitrate Range: 1,500-4,000 Kbps

I have tested several scenarios with setting the ‘startBitrate’ to a low level and found good results with following:

nano /etc/jitsi/meet/

Find the video-section and insert:

startBitrate: 500,
resolution: 720,
constraints: {
video: {
aspectRatio: 16 / 9,
height: {
ideal: 720,
max: 720,
min: 240

Part-2: Installation of Jibri: JAVA 8 (Jibri requires JAVA 8)

Check your java version-

java -version

The output should return with OpenJDK 8 installed. Now set the Java Home-

The returned console output shows us the path to JAVA 8 and we will copy this to set the Java Home Environment Variable variable:

nano ~/.bashrc 

Paste the following line (make sure to use the path that was returned in previous step):

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java

Save this and then source the file:

source ~/.bash_profile

And check the Java Home:


This should return:


Miscellaneous packages

We will install all miscellaneous packages EXCEPT default-jre-headless:

apt update && install unzip ffmpeg curl alsa-utils icewm xdotool xserver-xorg-input-void xserver-xorg-video-dummy -y

ALSA and Loopback Device. Set up the module to be loaded on boot:

echo "snd-aloop" >> /etc/modules

Load the module into the running kernel:

modprobe snd-aloop

Check to see that the module is already loaded:

lsmod | grep snd_aloop

This should return (something like):

snd_aloop 24576 0
snd_pcm 106496 1 snd_aloop
snd 86016 3 snd_aloop,snd_timer,snd_pcm

Google Chrome stable & Chromedriver. Install the latest Google Chrome stable build:

curl -sS -o - | apt-key add
echo "deb [arch=amd64] stable main" > /etc/apt/sources.list.d/google-chrome.list
apt update && apt install google-chrome-stable -y

Add chrome managed policies file and set CommandLineFlagSecurityWarningsEnabled to false. It will hide warnings in Chrome. You can set it like so:

mkdir -p /etc/opt/chrome/policies/managed
echo '{ "CommandLineFlagSecurityWarningsEnabled": false }' >>/etc/opt/chrome/policies/managed/managed_policies.json

Chromedriver is also required and can be installed like so:

unzip ~/ -d ~/
rm ~/
mv -f ~/chromedriver /usr/local/bin/chromedriver
chown root:root /usr/local/bin/chromedriver
chmod 0755 /usr/local/bin/chromedriver

Jitsi/Jibri Debian Repository

The Jibri packages can be found in the stable repository:

wget -qO - | sudo apt-key add -
sh -c "echo 'deb stable/' > /etc/apt/sources.list.d/jitsi-stable.list"
apt update && apt install jibri -y

We want to make sure that user ‘jibri’ is part of the necessary groups:

usermod -aG adm,audio,video,plugdev jibri

With these steps, we have now the basic setup of Jibri done, but the service is not active (yet).

Part-3: Configuring Jitsi and Jibri

Prosody configuration

Create the internal Multi User Component (MUC) and the the recorder virtual host entry, login to server “jitsi” and:

nano /etc/prosody/conf.avail/

At the end of this file, add a dedicated section:

-- internal muc component, meant to enable pools of jibri and jigasi clients
Component "" "muc"
modules_enabled = {
storage = "memory"
muc_room_cache_size = 1000

VirtualHost ""
modules_enabled = {
authentication = "internal_plain"

Reload prosody:

/etc/init.d/prosody reload

Create two users for Jibri (user: jibri and user: recorder):

prosodyctl register jibri JibrisPass
prosodyctl register recorder RecordersPass

(Important: take note of these passwords, we will need them later also on server “jibri”!)

Jicofo configuration

Set the Multi User Component (MUC) to look out for Jibri:

nano /etc/jitsi/jicofo/

In this file, add two lines:

Reload jicofo:

/etc/init.d/jicofo reload

Jitsi Meet configuration

Make sure we have the button for recording and/or streaming in our config:

nano /etc/jitsi/meet/

Look for following lines, uncomment the line and set value to ‘true’ or add if the line does not exist:

fileRecordingsEnabled: true, // If you want to enable file recording
liveStreamingEnabled: true, // If you want to enable live streaming
hiddenDomain: '',

Make sure we have the menu-option for recording and streaming available:

nano /usr/share/jitsi-meet/interface_config.js

Look for the section TOOLBAR_BUTTONS and make sure that the array contains ‘recordings’ and ‘livestreaming’. We need to configure the xmpp environments and the directory where we want to store our recordings:

nano /etc/jitsi/jibri/config.json

Change settings according to:

"finalize_recording_script_path": "/path/to/",
"xmpp_environments": [
"name": "prod environment",
"xmpp_server_hosts": [
"xmpp_domain": "",
"control_login": {
// The domain to use for logging in
"domain": "",
// The credentials for logging in
"username": "jibri",
"password": "JibrisPass"
"control_muc": {
"domain": "",
"room_name": "JibriBrewery",
"nickname": "jibri-nickname"
"call_login": {
"domain": "",
"username": "recorder",
"password": "RecordersPass"
"room_jid_domain_string_to_strip_from_start": "conference.",
"usage_timeout": "0"

Now we create the directory for the recordings and make sure user ‘jibri’ can write here:

mkdir /srv/recordings
chown jibri:jitsi /srv/recordings

Restart jibri service:

service jibri restart

This is all we need to do on server “jibri”.

Everything above this section needs to be changed on server “jibri”: “ 20”

Testing recording

Once all these changes were in place, I even rebooted both servers. On the server “jibri”, the jibri service does not automatically start, so keep in mind to do so manually if needed.

Now I open my 12 and start a meeting ‘test’. Once I Am presented with my videostream, I open the menu and choose ‘Start recording’. After some time to load, the recording was started. So after some seconds, I open the menu again and choose ‘Stop recording’.

On the server, I found the mp4 file of the recording in a sub-folder with a random generated folder-name:

Mission accomplished!

Last but not the least, if you reboot the server, you have to start jibri service-

systemctl restart jibri



4 thoughts on “Installing Jitsi and Jibri on Same Machine

    • The published configuration works on my many installations. Do not mix with other configuration reference- which might not work. Can you share the kernel version that your droplet has?

  1. Hi,
    We have followed your steps, but our Nginx is not able to start and showing following error:
    Job for nginx.service failed because the control process exited with error code. See “systemctl status nginx.service” and “journalctl -xe” for details.

    Can you help?

    • Try to check if the nginx is properly installed and if port 80+443 are taken by some other application (such as Apache). Port conflict is an error probably. As the error itself is self-explaantory- try to run this command- “journalctl -xe” and see the prints. You can also apply “netstat -plntu” to see what other application or service might have occupied your port 80+443. Thnaks.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.