Jitsi Installation on Artix Linux

Gokberk Gunes   —   Self-Hosting · Server

Table of Contents

This article will guide you through setting up server side of a video conference program called Jitsi on systemd-free GNU/Linux distributions. The installation will be done on bare metal, not through any vitalization. Some commands are given explicitly for Arch-based distributions and systems using runit as init, though the commands can be easily altered for other init systems.

What is Jitsi?

Jitsi is an open-source video conference software. It’s similar to Zoom, Google Meet, Microsoft Teams, except for being self-hosted. Even though the self-hosting part generates a layer of complexion for the hosting party, the freedom and extensibility of Jitsi are indispensable.

Why did I write this guide?

Typically, Jitsi and some other parties provide much easier ways to deploy Jitsi on a server. However, all of these ways require systemd, abstract the installation process, and limit the configurability.

Note: The guide is adapted from Arch Linux’ wiki page, Celogreek’s guide. Yet, it still was a hassle because of the compilations of the programs and et cetera.

Below you may find references, useful links accompany this guide.

Install Preparations

Switch to the root account. You must keep using root account throughout the whole guide.
Note: If you do not have doas, you should replace it with sudo. Alternatively, you can directly call su.

doas su

Now, you need to install the required programs. These programs are either run-time or compile-time dependencies.

pacman -S git gnupg nginx-mainline curl jdk11-openjdk maven npm unzip prosody

Add the below piece of code to set a local loop back. This code will allow programs to talk to each other.

/etc/hosts:
127.0.0.1 YOUR_DOMAIN auth.YOUR_DOMAIN
::1 YOUR_DOMAIN auth.YOUR_DOMAIN

Jicofo Installation

Cloning and Installing

In this section, you will obtain the source code from official repositories, compile the source and move them to an appropriate location.

Clone the official repository.

mkdir /srv/http/jitsi/sources && cd /srv/http/jitsi/sources
git clone "https://github.com/jitsi/jicofo.git"
cd jicofo

Compile the source code to executables.

mvn package -DskipTests -Dassembly.skipAssembly=false

Move the compiled files to the server’s system folders.

unzip jicofo/target/jicofo-*.zip -d /srv/http/jitsi/
mv /srv/http/jitsi/jicofo-* /srv/http/jitsi/jicofo
rm /srv/http/jitsi/jicofo/jicofo.bat

Creating and Modifying Configuration Files

Creation of the configuration files for Jicofo and their setup will be done here. Beware that this part requires manual edits to the specified files.

Move the configuration files to a sensible location.

mkdir -p /etc/jicofo/
mv lib/logging.properties /etc/jicofo
mv jicofo-selector/src/main/resources/reference.conf /etc/jicofo/jicofo.conf

In the configuration file, you have to change the below sections to your domain address. If these lines are they are commented out with either // or #, remove these comment characters.

/etc/jicofo/jicofo.conf:
xmpp {
	...
	conference-muc-jid = conference.meet.berksen.net

	...

      client-proxy = focus.meet.berksen.net

	...
    }

Create a user and a group for jicofo.

echo "g jitsi\nu jicofo -:jitsi - /var/lib/jicofo" > /usr/lib/sysusers.d/jicofo.conf
sysusers

In below file modify JICOFO_HOSTNAME, JICOFO_AUTH_DOMAIN, JICOFO_AUTH_PASSWORD with your information. Change meet.berksen.net to your domain address and set password1. You may generate a randomized password with openssl rand -hex 16.

/etc/jicofo/config:
# Jitsi Conference Focus settings
# sets the host name of the XMPP server
export JICOFO_HOST=localhost

# sets the XMPP domain (default: none)
export JICOFO_HOSTNAME=meet.berksen.net

# sets the XMPP domain name to use for XMPP user logins
export JICOFO_AUTH_DOMAIN=auth.meet.berksen.net

# sets the username to use for XMPP user logins
export JICOFO_AUTH_USER=focus

# the password to use for XMPP user logins (focus user)
export JICOFO_AUTH_PASSWORD=password1

# extra options to pass to the jicofo daemon
export JICOFO_OPTS=""

# adds java system props that are passed to jicofo (default are for home and
# logging configuration file)
export JAVA_SYS_PROPS="\
 -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc\
 -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jicofo\
 -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jicofo\
 -Djava.util.logging.config.file=/etc/jicofo/logging.properties\
 -Dconfig.file=/etc/jicofo/jicofo.conf\
 -Djava.util.prefs.userRoot=/var/lib/jicofo\
"

Create the communicator file. Modify adress meet.berksen.net below.

echo "org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.meet.berksen.net" > /etc/jicofo/sip-communicator.properties

Runit Script Generation

There is a need to supervise, execute, log the jicofo. Here, a runit script will be created and activated to provide these needs.

Create a file for the jicofo. This will do the logging and running jicofo.

mkdir -p /etc/runit/sv/jicofo/log
touch /etc/runit/sv/jicofo/log/run /etc/runit/sv/jicofo/run
chmod +x /etc/runit/sv/jicofo/log/run /etc/runit/sv/jicofo/run

Alter the run file as shown below.

/etc/runit/sv/jicofo/run:
#!/bin/sh
exec 2>&1; set -e

# Read configuration file which sets other configuration files' locations.
. /etc/jicofo/config

exec chpst -u jicofo:jitsi /srv/http/jitsi/jicofo/jicofo.sh --host=$JICOFO_HOST --domain=$JICOFO_HOSTNAME --user_name=$JICOFO_AUTH_USER --user_domain=$JICOFO_AUTH_DOMAIN $JICOFO_OPTS

Edit the logging script as following.

/etc/runit/sv/jicofo/log/run:
#!/bin/sh
exec 2>&1; set -e

[ -d /var/log/jitsivid ] || install -dm 755 /var/log/jitsivid

exec svlogd -tt /var/log/jitsivid

Start the runit service.

ln -s /etc/runit/sv/jicofo /run/runit/service

Jitsi-Videobridge Installation

Cloning and Installing

At this point, the source code from official repositories will be downloaded. The source code will be compiled. Then, compiled files will be moved to an appropriate location.

Clone the repository.

cd /srv/http/jitsi/sources/
git clone "https://github.com/jitsi/jitsi-videobridge.git"
cd jitsi-videobridge

Compile jitsi-videobridge.

mvn package -DskipTests -Dassembly.skipAssembly=true install

Move the compiled files to the server’s system folders.

unzip jvb/target/jitsi-videobridge-*.zip -d /srv/http/jitsi/
mv /srv/http/jitsi/jitsi-videobridge-* /srv/http/jitsi/jitsi-videobridge
rm /srv/http/jitsi/jitsi-videobridge/jvb.bat

Creating and Modifying Configuration Files

Configuration files for jitsi-videobridge will be done here. Please note that there are parts you need to edit manually. Guidance is given on what and how to edit.

Move the java configuration and kernel setting files to a better location.

mkdir -p /etc/jitsi-videobridge/
mv jvb/lib/logging.properties config/callstats-java-sdk.properties /etc/jitsi-videobridge
mkdir -p /etc/sysctl.d
mv config/20-jvb-udp-buffers.conf /etc/sysctl.d

Create a user and a group for jitsi-videobridge.

echo "g jitsi\nu jvb -:jitsi - /var/lib/jitsi-videobridge" > /usr/lib/sysusers.d/jitsi.conf
sysusers

Modify JVB_HOSTNAME to your domain; in other words alter meet.berksen.net reflecting your domain. Set password2. You may generate a randomized password with opensll rand -hex 16
Note: The configuration file could have been left empty at this point; the server would still be working. However, it will be needed if a web socket is used.

/etc/jitsi-videobridge/config:
# Jitsi Videobridge settings

# sets the XMPP domain (default: none)
export JVB_HOSTNAME=meet.berksen.net

# sets the hostname of the XMPP server (default: domain if set, localhost otherwise)
export JVB_HOST=

# sets the port of the XMPP server (default: 5275)
export JVB_PORT=5347

# shared secret used to authenticate to the XMPP server (jvb user)
export JVB_SECRET=password2

# extra options to pass to the JVB daemon
export JVB_OPTS="--apis=,"

# adds java system props that are passed to jvb (default are for home and logging configuration file)
export JAVA_SYS_PROPS="\
  -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc\
  -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jitsi-videobridge\
  -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi-videobridge\
  -Djava.util.logging.config.file=/etc/jitsi-videobridge/logging.properties\
  -Djava.util.prefs.userRoot=/var/lib/jitsi-videobridge\
"
# Below configuration belongs to JAVA_SYS_PROPS, but causes jitsi to not work.
#  -Dconfig.file=/etc/jitsi-videobridge/jvb.conf\

Create the communicator file. Change shard.DOMAIN to your domain. Set password2 as what you set earlier. Modify domain part shard.MUC_JIDS to your domain. Generate a Shard.MUC_NICKNAME with uuidgen command.

/etc/jitsi-videobridge/sip-communicator.properties:
org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=meet-jit-si-turnrelay.jitsi.net:443
org.jitsi.videobridge.ENABLE_STATISTICS=false
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=localhost
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.meet.berksen.net
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=password2
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.meet.berksen.net
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=uuid

Runit Script Generation

There is a need to supervise, execute, log the jitsi-videobridge. Here, a runit script will be created and activated to provide these needs.

Create a file for the jitsi-videobridge. This will do the logging and running jitsi-videobridge.

mkdir -p /etc/runit/sv/jitsi-videobridge/log
touch /etc/runit/sv/jitsi-videobridge/log/run /etc/runit/sv/jitsi-videobridge/run
chmod +x /etc/runit/sv/jitsi-videobridge/log/run /etc/runit/sv/jitsi-videobridge/run

Alter the run file as shown below.

/etc/runit/sv/jitsi-videobridge/run:
#!/bin/sh
exec 2>&1; set -e


# Read configuration file which sets other configuration files' locations.
. /etc/jitsi-videobridge/config

exec chpst -u jvb:jitsi /srv/http/jitsi/jitsi-videobridge/jvb.sh $JVB_OPTS

Edit the logging script as following.

/etc/runit/sv/jitsi-videobridge/log/run:
#!/bin/sh
exec 2>&1; set -e

[ -d /var/log/jitsivid ] || install -dm 755 /var/log/jitsivid

exec svlogd -tt /var/log/jitsivid

Start the runit service.

ln -s /etc/runit/sv/jitsi-videobridge /run/runit/service

Jitsi-Meet Installation

Cloning and Installing

In this section, the source code from official repositories will be downloaded. The source code will be compiled. Then, compiled files will be moved to an appropriate location.

Clone the repository.

mkdir -p /srv/http/jitsi/; cd /srv/http/jitsi
git clone "https://github.com/jitsi/jitsi-meet.git"
cd jitsi-meet/

Compile jicofo.
Note: make command for jitsi-meet will not work cause of ram limitations in java settings. That’s why you are exporting NODE_OPTIONS environmental variable as shown below.

export NODE_OPTIONS="--max-old-space-size=8192"
npm install
make

Creating and Modifying Configuration Files

Configuration files for jitsi-meet will be done here. Please note that there are parts you need to edit manually. Guidance is given on what and how to edit.

Move the compiled files to the server’s system folders.
Note: There used to be a configuration file called logging_config.js but it is now merged into config.js. The other file, interface_config.js, is also planned to be merged into config.js in the future.

mkdir -p /etc/jitsi-meet
ln -sf /srv/http/jitsi/jitsi-meet/interface_config.js /etc/jitsi-meet/
ln -sf /srv/http/jitsi/jitsi-meet/config.js /etc/jitsi-meet/

Edit the main configuration file. Change below options for your own domain.

/etc/jitsi-meet/config.js:
var config = {
    ...
	hosts: {
		// XMPP domain.
		domain: 'meet.berksen.net',

		...
		// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
		muc: 'conference.meet.berksen.net',
	},

	// BOSH URL. FIXME: use XEP-0156 to discover it.
	bosh: '//meet.berksen.net/http-bind',

	...
}

Prosody Configuration

Prosody is found in repositories as in pre-compiled form. Therefore, there is only configuration is required for it.

Creating and Modifying Configuration Files

Make a configuration folder. Download configuration file from jitsi-meet repository. Include the configuration file to prosody’s settings.

mkdir -p /etc/prosody/conf.d
curl "https://raw.githubusercontent.com/jitsi/jitsi-meet/master/doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example" > /etc/prosody/conf.d/jitsi.cfg.lua
echo "Include \"conf.d/*.cfg.lua\"" >> /etc/prosody/prosody.cfg.lua

Change domain names to your domain as described below. In this file, you should replace all domain names with yours. (If desired, all jitmeet.example.com occurrences can be changed to your domain too.)

/etc/prosody/conf.d/jitsi.cfg.lua:
Replace all occurances:
    "jitmeet.example.com" with "meet.berksen.net"
    "focusUser@auth.jitmeet.example.com" with "focus@auth.meet.berksen.net"
Vim users can run following command:
:%s/jitmeet\.example\.com/meet\.berksen\.net/g

Set plugin paths as shown below.

/etc/prosody/conf.d/jitsi.cfg.lua:
plugin_paths = { "/srv/http/jitsi/jitsi-meet/resources/prosody-plugins/" }

Certificate Generation

In order to generate certificates, you muust have CNAME records by your domain provider. There are going to be some warnings about certificate for hosts. The warnings are not important since all warnings are about virtual hosts, which you do not need certificates for. Only meet.berksen.net and auth.meet.berksen.net are important.

certbot --nginx certonly -d meet.berksen.net
certbot --nginx certonly -d auth.meet.berksen.net

Create a letsencrypt renewal hook. This way, whenever you renew the letsencrypt certificates, prosody certificates will automatically imported.

/etc/letsencrypt/renewal-hooks/deploy/prosody:
#!/usr/bin/sh
/usr/bin/prosodyctl --root cert import /etc/letsencrypt/live

Make the hook file executable.

chmod +x /etc/letsencrypt/renewal-hooks/deploy/prosody

After running certbot, you will get configuration and certificate files.

  • Configuration is written to /var/lib/prosody/meet.berksen.net.cnf,
  • Certificate is written to /var/lib/prosody/meet.berksen.net.crt.

Now change keys and certificates, as indicated above.

/etc/prosody/conf.d/jitsi.cfg.lua:
VirtualHost "meet.berksen.net"
	...
	ssl = {
		key = "/etc/prosody/certs/meet.berksen.net.key";
		certificate = "/etc/prosody/certs/meet.berksen.net.crt";
	}

	...

VirtualHost "auth.meet.berksen.net"
	ssl = {
		key = "/etc/prosody/certs/auth.meet.berksen.net.key";
		certificate = "/etc/prosody/certs/auth.meet.berksen.net.crt";
	}
	authentication = "internal_hashed"

Nginx & Jitsi Connection

Make a configuration folder and a configuration file as jitsi.conf.

mkdir -p /etc/nginx/enabled-sites
mkdir -p /etc/nginx/sites
curl "https://github.com/jitsi/jitsi-meet/blob/master/doc/debian/jitsi-meet/jitsi-meet.example" > /etc/nginx/sites
mv /etc/nginx/sites/jitsi-meet.example /etc/nginx/sites/jitsi.conf

Activate the configuration file in nginx by symlinking it.

ln -sf /etc/nginx/sites/jitsi.conf /etc/nginx/enabled-sites

Modify nginx’ configuration file to include all the configuration files located in enabled-sites folder. The include statement must go inside the http part.

/etc/nginx/nginx.conf:
http {

	...

	include /etc/nginx/enabled-sites/*.conf;

	...

}

Alter jitsi.conf to include your domain names, SSL certificates, installation file paths.

/etc/nginx/enabled-sites/jitsi.conf:
server {
	...

	server_name meet.berksen.net;

	...

	ssl_certificate /etc/prosody/certs/meet.berksen.net.crt;
	ssl_certificate_key /etc/prosody/certs/meet.berksen.net.key;

	root /srv/http/jitsi/jitsi-meet;

	location = /config.js {
		alias /srv/http/jitsi/jitsi-meet/config.js;
	}

	location = /external_api.js {
		alias /srv/http/jitsi/jitsi-meet/libs/external_api.min.js;
	}

	...

	# ensure all static content can always be found first
	location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
	{
		alias /srv/http/jitsi/jitsi-meet/$1/$2;

		...
	}

	...

	location ~ ^/([^/?&:'"]+)/config.js$
	{

		...
		alias /srv/http/jitsi/jitsi-meet/config.js;
	}

Run the following command to check syntax errors in nginx configuration file.

nginx -t

Register Users

Register for jicofo. You may check your password1 in /etc/jicofo/config.

prosodyctl register focus auth.meet.berksen.net password1

Register for jitsi-videobridge. You may check your password2 at /etc/jitsi-videobridge/config.

prosodyctl register jvb auth.meet.berksen.net password2

Subscribe to mod_roster_command.

prosodyctl mod_roster_command subscribe focus.meet.berksen.net focus@auth.meet.berksen.net

Restart runit services.

sv restart prosody
sv restart jitsi-videobridge
sv restart jicofo
sv restart nginx

Websocket Activations

This part of the installation is done in order to decrease server’s load.

Jitsi-Meet Websocket Activation

Activate websocket on jitsi-meet side.

/etc/jitsi-meet/config.js:
var config = {
	...

	// Websocket URL
	websocket: 'wss://meet.berksen.net/xmpp-websocket',

	...
}

Prosody Websocket Activation

Activate the websocket module on prosody configuration file.

/etc/prosody/conf.d/jitsi.cfg.lua:
consider_websocket_secure = true;
cross_domain_websocket = true;

VirtualHost "meet.berksen.net"
	...

	modules_enabled = {
		...
		"websocket"; -- Enable websocket.
		...
	}

Jitsi-Videobridge Websocket Activation

Copy the reference jitsi-videobridge configuration file to your system.

cp /srv/http/jitsi/sources/jitsi-videobridge/jvb/src/main/resources/reference.conf /etc/jitsi-videobridge/

Set sockets on the jitsi-videobridge.

/etc/jitsi-videobridge/reference.conf:
videobridge {
	http-servers {
		...
		public {
			...
			port = 9090
			...
		}
		...
	}
	...
	websockets {
		...
		enabled=true
		server-id="default-id"
		tls=true
		domain="meet.berksen.net:443"
		...
	}
}

Add socket info back to the jitsi-videobridge configuration file.

/etc/jitsi-videobridge/config:
...
# adds java system props that are passed to jvb (default are for home and logging configuration file)
export JAVA_SYS_PROPS="\
  -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc\
  -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jitsi-videobridge\
  -Dconfig.file=/etc/jitsi-videobridge/reference.conf\
  -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi-videobridge\
  -Djava.util.logging.config.file=/etc/jitsi-videobridge/logging.properties\
  -Djava.util.prefs.userRoot=/var/lib/jitsi-videobridge\
"

Restart the services.

sv restart prosody
sv restart jitsi-videobridge

Disallow Room Creations

The rationale is to stop random people to create and use rooms, this server is not free to use. When there is no administrator is online, other users has to wait for an administrator. These users cannot create or use a room without an administrator.

Add below to jicofo’s sip communicator file, use correct domain name.

/etc/jicofo/sip-communicator.properties:
org.jitsi.jicofo.auth.URL=XMPP:meet.berksen.net

Alter the jitsi-meet’s configuration file to reflect your domain name.

/etc/jitsi-meet/config.js:
var config = {
	...
	host: {
		...
		// When using authentication, domain for guest users.
		anonymousdomain: 'guest.meet.berksen.net',
		...
	},
	...
}

Modify jitsi’s prosody configuration file. Change authentification for main domain, add guest domain with anonymous authentication. Use same modules you use for your main virtualhost but remove muc_lobby_rooms from it.

/etc/prosody/conf.d/jitsi.cfg.lua:
...
VirtualHost "meet.berksen.net"
	...
	authentification = "internal_plain"

-- add guest virtual host to allow anonymous user to join your room
VirtualHost "guest.meet.berksen.net"
        authentication = "anonymous"
        c2s_require_encryption = false
	modules_enabled = {
		"bosh";
		"pubsub";
		"ping"; -- Enable mod_ping
		"websocket"; -- Enable websocket.
		"speakerstats";
		"external_services";
		"conference_duration";
		"muc_breakout_rooms";
		"av_moderation";
    }
    ...

Now, register users as many as required. The user_name and user_password will be used to log into the server.

prosodyctl register user_name meet.berksen.net user_password

NOTE: If you need to check the current prosody users and their passwords, go to /var/lib/prosody.

Restart services.

sv restart jicofo
sv restart prosody

You may check current accounts and their passwords below.

/var/lib/prosody/domain_name/accounts/name.dat:
return {
	["password"] = "account_password";
};