Running Jitsi Meet as a Docker Container, behind NGINX, on Ubuntu Server 24.04: A Tutorial.
I got a Jitsi Meet server running this evening.
It was a hassle. I hope to provide you with better directions.
I assume you're using Ubuntu Server 24.04, running nginx
, with both the docker.io
and docker-compose
packages installed. If not, please change OS if necessary, and run
sudo apt install -y nginx docker.io docker-compose
Part One: What is Jitsi Meet?
Imagine Zoom, but with fewer logins and less overall Zoom-ness. It's video conferencing.
Part Two: Getting Started
This section relies heavily on the documentation at https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/#quick-start. You can read along in your book! You'll know it's time to turn the page when you hear this sound: [screams of the damned in the circle of Hell reserved for those who write poor or incomplete documentation]
Here we go.
- Grab the latest Docker release, in the strangest, most "we're doing it OUR WAY" way you'll hopefully see all month:
wget $(curl -s https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep 'zip' | cut -d\" -f4)
- Unzip that puppy. The filename will probably be something like
stable-318273731
, so:
unzip stable-
(and hit Tab
to auto-complete the filename)
- Enter that directory:
cd jitsi-docker
(again, hit Tab
to auto-complete the directory name)
- Create an
.env
file by copying the example provided. This file is where almost all the things we'll need to change reside.
cp env.example .env
- There's a bash script in your
jitsi-docker-
whatever directory that will add some passwords to your brand new.env
file. Let's run it.
./gen-passwords.sh
- We need some new directories for configuration files. (Not that we'll touch those files today. The directories just need to be present.)
mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
Part Three: We Enter the .env Weeds
This is where we break from the existing documentation. All of the things we'll do now are part of the docs; they are not listed in order as a series of straightforward tasks. That's why it was a hassle for me, and that's why I write this for you.
-
Open your
.env
file. It's time to make some changes. -
TZ=
should be set to your local time zone code. I live in the US in the Central time zone, so mine reads:TZ=America/Chicago
. You can find a list of time zone codes on Wikipedia. -
PUBLIC_URL=
is commented out with a#
. Remove that#
and change the line to point to the URL you want people to visit. It should look likePUBLIC_URL=https://example.URL.tld
, with your URL instead ofexample.URL.tld
. -
JVB_ADVERTISE_IPS=
tells everyone where to find shared files. If your server is within your LAN, and you want to connect from home, you'll need to add the local IP of your server. Mine ended up looking like:
JVB_ADVERTISE_IPS=127.0.0.1,192.168.1.84,78.188.19.84
where:
-
127.0.0.1
is localhost, of course, -
192.168.1.84
is the LAN address of the server, and -
78.188.19.84
is the server's public IP address. -
We need to set some environment variables that tell the Docker container not to bother with HTTPS connections. There's no point when nginx is communicating directly with the Docker container on the same machine. Add these lines to your
.env
file next:
DISABLE_HTTPS=1
ENABLE_HTTP_REDIRECT=0
ENABLE_LETSENCRYPT=0
- Weirdly, the line that tells the container to restart automagically in most cases is commented out. Remove the
#
so it looks like:
RESTART_POLICY=unless-stopped
- That's all we're changing here in the
.env
file. Save and exit.
Part Four: docker-compose.yml, Too?
Yuuuuuuuup, we're going to edit the docker-compose.yml
file next. Gratefully, we don't need to make as many changes here.
- Find the section that reads:
- '${HTTP_PORT}:80'
- '${HTTPS_PORT}:443'
We don't need the container to bind ports 80 and 443 to every network interface. The lines should, instead, look like
- '127.0.0.1:${HTTP_PORT}:80'
- '127.0.0.1:${HTTPS_PORT}:443'
- Weirdly, the default ports in the
jvb
video bridge section gave me issues. I changed them slightly. Find the
- '127.0.0.1:${JVB_COLIBRI_PORT:-8080}:8080'
line and change the ports. I made the first one 8085
and the second 8044
. Doesn't matter much, so long as you pick ports you know aren't in use.
That's all for the docker-compose.yml
file. Save it and exit. We're getting so close.
Part Five: Oh Lord, NGINX
The fun never ends, eh? It's time to create a virtual host .conf
file for this puppy.
Head on over to where your virtual host files live, likely /etc/nginx/conf.d/
, and create a new file:
sudo nano meet.conf
The whole file should look something like this.
server {
server_name example.URL.tld;
index index.html;
location / {
proxy_pass http://localhost:8000;
}
location /xmpp-websocket {
proxy_pass http://localhost:8000/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /colibri-ws {
proxy_pass http://localhost:8000/colibri-ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Once you have that copied & pasted & edited to have a real URL, save and exit. Run sudo nginx -t
to ensure nginx approves of your code.
Also, we are running a web service; make sure ports 80
and 443
are allowed to make TCP connections to the server, as well as port 10000
via UDP. Add them to your
firewall rules, add them to your port forwarding on your router if need be; ensure visitors can connect via ports 80
, 443
, and 10000
.
Part Six: Hold On to Your Butts, We're Starting Up
Are you still in your jitsi-docker-jitsi-
whatever directory? If not, navigate back to it. Optionally cross your fingers, clench up, or whatever calms your anxiety. It's time to:
docker-compose up -d
If all goes well, you should see several messages about creating, then starting containers, and then a beautiful, error-report-free command line. Gosh, I hope that's what you see.
If so, you can restart nginx (sudo systemctl restart nginx
) and navigate to your URL. It is not fully functional yet, but the final steps are few and simple.
If the page loads, head back to your command line; we're installing certificates. (You have certbot
already installed to create certs for you, yes? If not, sudo apt install certbot
.)
This is likely the most run-of-the-mill portion of the tutorial. Run sudo certbot --nginx
, select the number of your new Jitsi URL from the list, and let certbot do its thing.
Part Seven: There Is No Part Seven
You did it! If you made it from the beginning of this tutorial to these words without encountering any flagrant, brain-breaking errors, you now have a working Jitsi Meet server. Enjoy chatting with family, friends, colleagues, and anyone else you need to video call.
Should you need to take your server down, the simplest (and cleanest) way to do so is to navigate back to your jitsi-docker-jitsi-meet
blahblah directory and use:
docker-compose down
When you're ready to bring the server back up, a simple docker-compose up -d
(from the same directory) will have you running again in moments.
If you found this tutorial useful, by all means, feel free to visit my Ko-Fi page and toss a buck my way. It took hours of poring through docs to get my instance up and running, and around 90 minutes to write this post; I wrote it because I needed a more straightforward, comprehensive guide to exist. Any monetary "thank you"s are secondary to knowing that there is at least one guide with a set of A, B, C, D, E steps: nothing omitted, nothing nonsensically divorced from its place in the process, nothing a three-quarter page scroll away from when the info is actually useful.
Goodbye—Mwah!—and good night! BANG!