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 like PUBLIC_URL=https://example.URL.tld, with your URL instead of example.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-meetblahblah 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!