How to Self Host Jitsi Meet With Docker
Complete beginner's guide to deploy a Jitsi Meet instance with Docker on a Linux server.
Jitsi Meet is an open source videoconferencing software that you can self-host. It is a good alternative to proprietary services like Google Meet or Zoom.
Jitsi Meet can be integrated with other open source tools like Nextcloud, Rocket.Chat or Synapse (Matrix implementation) to give you a comprehensive solution.
With some limitations, Jitsi Meet can be used for free on their server. For premium features, you can opt for Jitsi as a Service from Jitsi developers. You may also deploy it on your own server? I'll help you with the self-hosting part.
Deploying Jitsi Meet with Docker
Deploying Jitsi is incredibly easy with Docker. I am going to show you the steps for Jitsi deployment. I'll cover both reverse proxy and regular method.
Prerequisites
There are a few things that need to be taken care of before proceeding.
Basic knowledge of Docker and containers: This isn't a must, like all of our tutorials, but nice to have.
A custom domain: This deployment won't be IP-served, that is I will walk you through the deployment under an actual domain (or subdomain) with HTTPS. Deployments like HTTP://[some IP]:[some port] are fine for testing, but don't serve any purpose in these guides.
A Linux server either a physical one or in the cloud: I recommend using Linode but you can use any other provider like DigitalOcean, Vultr or UpCloud. Deploying under AWS can be very platform-specific and I won't be talking about that here.
As per official recommendation, a server with 4 GB memory with a dual-core processor would be suitable for around 10-20 users.
Optionally, our reverse proxy setup: If you want to put it behind a reverse proxy so that you can deploy several web services on the same server. If Jitsi is the only application that's going to run on the server, you don't need the reverse proxy.
Changing DNS records
Having a domain name isn't enough. You need to make sure the DNS records are in place as well. For this tutorial, I'm going to use a domain openexperiment.in which I've had lying around for quite a while.
Make sure you change all instances of the domain from the examples to your domain.
Once you have a domain and deployed a server (not with Jitsi, just the server), gather the server's IP addresses (IPv4 & IPv6 both), and add A and AAAA records for each respectively. After that's done, you'll also need to add a CNAME record. You can add a specific subdomain or like me, add a wildcard entry (if you are hosting it on the main domain).
See the screenshot below if you are still confused. I blurred the actual IP addresses (I am very secretive ... shhh).
You may have to wait some time for the DNS changes to take effect. You can check that using the ping command.
ping
the domain until you see your server's IP address like this -
❯ ping openexperiment.in -4
PING openexperiment.in (xxx.xxx.xxx.xxx) 56(84) bytes of data.
^C64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=55 time=36.6 ms
--- openexperiment.in ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 36.610/36.610/36.610/0.000 ms
You can also use the dig command to check the DNS records.
dig openexperiment.in +nocmd +nocomments
You should see something like the following
❯ dig openexperiment.in +nocmd +nocomments
;openexperiment.in. IN A
openexperiment.in. 2970 IN A xxx.xxx.xxx.xxx
;; Query time: 1 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun Mar 07 11:38:20 IST 2021
;; MSG SIZE rcvd: 62
Understand the Jitsi Meet components
Before moving forward I believe it's helpful to know what these components are, and why they're important, along with which ones you're going to be using for this deployment.
If you don't care for this, obviously skip to the deployment section of this article.
jitsi/web:latest: The web UI of Jitsi Meet, which you see on your browser, is inside this image. Along with Nginx for the webserver.
jitsi/prosody:latest: This is the XMPP server, this is what's responsible for the audio/video calls or the text chats. This can be considered the heart of Jitsi.
jitsi/jicofo:latest: The focus component of the XMPP server, responsible for managing video sessions between the participants and the videobridge, in other words, this is what manages the conferences. This is another mandatory component of Jitsi.
jitsi/jvb:latest: The Jitsi Videobridge is responsible for relaying the incoming video channels to all the participants.
These are the mandatory parts of an operational Jitsi deployment, and I will only be using them for this guide. There are other components like Jibri, Jigasi, but since they're optional, I'm going to leave them out for now.
Enough reading, it's time for some hands-on work.
Clone the docker-jitsi-meet repository
This repository contains all the files that we're going to need for this deployment (with obviously some modifications).
Clone the repository and change your PWD
to the cloned directory.
git clone https://github.com/jitsi/docker-jitsi-meet jitsi
cd jitsi
Start modifying the environment variables
Since you are using Docker, you have to modify some environment variables. Start by copying the example configuration file.
cp env.example .env
Now open the .env
file, and look at the first 6 environment variables.
Since all these components are basically some sort of servers running in containers, you need a way to make sure the servers are really who they say they are. These secrets are there for that reason. The clients must authenticate first before establishing a connection.
You don't have to set these secrets by yourself. There's already a script there to make your life easier. Run the following command while you're inside the repository directory
./gen-passwords.sh
Once run, you can reopen the .env
file, and the secrets should be filled out.
You won't be needing all those secrets for this deployment, but leave them be, there's no need to remove or comment them out.
There now are going to be three subsections here, one for the common variable assignments (reverse proxy or no reverse proxy), another for the reverse proxy, and the last one for no reverse proxy. All of them go to the .env file.
Common variables (for both reverse proxy and non-reverse proxy method)
Here are the variables common to both deployment methods and you add them in the .env file.
CONFIG: You can change the value of this, but it isn't necessary. The value of this variable is a directory in your host, which will be bind-mounted inside the containers to store persistent data. So modifying this is entirely up to you.
PUBLIC_URL: The domain Jitsi is going to be hosted on (with the protocol). In my case the value is https://meet.openexperiment.in
ENABLE_AUTH: Do you want authentication? With authentication, the user is going to have to put in a username and a password before they can join or create a meeting. If so, uncomment this line and make sure it's set to 1.
AUTH_TYPE: If you'd set ENABLE_AUTH to 1, then set this one to "internal". I won't go over LDAP or JWT authentication in this article.
RESTART_POLICY: Restart policy of the containers. The default is unless-stopped
. I prefer always
or on-failure
.
TZ: Set this to your system's timezone. Since my servers are running in UTC timezone, I don't have to change it.
Variables for non-reverse proxy method
If you are not using reverse proxy, you should add these variables to the .env file:
HTTP_PORT, HTTPS_PORT: Change these to 80 and 443 respectively. These are the ports your container is going to bind its to.
ENABLE_LETSENCRYPT: Set this to 1, you need HTTPS.
LETSENCRYPT_DOMAIN & LETSENCRYPT_EMAIL: The domain your instance will be hosted on, and your email id for your certificate-related notifications.
ENABLE_HTTP_REDIRECT: Set this to 1, HTTP traffic must be relayed to HTTPS.
ENABLE_HSTS: This will, in a way force the browsers to use a trusted connection. Set this to 1.
Variables required for reverse proxy
If you have opted for the reverse proxy, you should add these variables to the .env file:
DISABLE_HTTPS: Since HTTPS is going to be handled by your reverse proxy's web server, you don't need to have HTTPS enabled from Jitsi itself.
ENABLE_HTTP_REDIRECT: Not necessary, set this to 0. HTTP/HTTPS is going to be handled by our reverse proxy.
VIRTUAL_HOST & LETSENCRYPT_HOST: These variables are not there by default. Add these, and for the values, use the domain name where your instance is going to be hosted. For more information read my revere proxy article.
[ONLY IF USING REVERSE PROXY] Modify the compose file
Open the file docker-compose.yml
in your favorite text editor.
The only service definition that needs editing is the web service. Modify it according to the following list
- Remove the ports section. You no longer need to bind any port from your container to the host.
- Add another network, the same network that is used in your reverse proxy configuration.
- Define the network at the end of the compose file like so
networks:
net:
external: true
Assuming the network name is net
, change it to whatever you set yours to.
- Add the environment variables
VIRTUAL_HOST
&LETSENCRYPT_HOST
like so
- VIRTUAL_HOST
- LETSENCRYPT_HOST
Deploy the containers
Once all the editing is done, you can deploy Jitsi with docker-compose up -d
command.
Make sure your reverse proxy containers are running IF you opted for reverse proxy method.
You are almost done with the Jitsi Meet deployment except for the last step which is to create authenticated users for your Jitsi server.
Creating authenticated users
If you enabled authentication (with ENABLE_AUTH
), you're going to need to register the users before you can use Jitsi.
To do so is quite simple. Head over to the cloned repository directory and run a command similar to the following
docker-compose exec prosody prosodyctl --config=/config/prosody.cfg.lua register [USERNAME] meet.jitsi [PASSWORD]
You can also remove a user using the unregister
command like I've shown here:
docker-compose exec prosody prosodyctl --config=/config/prosody.cfg.lua unregister [USERNAME] meet.jitsi
Finally, you can go ahead and check the Jitsi Meet front end on the designated URL in a web browser:
Still have questions or suggestions? Please feel free to drop a comment.
If you like this tutorial and would like to see us produce more such helpful content, please consider opting for Pro membership or make a one time donation to support us :)