Self-Host Jitsi Meet with Docker: Take Control of Your Video Calls

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Why Reclaim Your Video Privacy?

Big Tech platforms often treat your meeting metadata as a product to be analyzed. Every time you launch a call on a public provider, you hand over logs, IP addresses, and usage patterns to a third party. For my HomeLab, I wanted a setup where I owned the entire stack—from the encrypted streams to the access controls.

Jitsi Meet has emerged as the most reliable open-source alternative to proprietary tools like Zoom or Teams. It offers full encryption, requires no guest accounts, and runs efficiently inside Docker. Mastering this deployment is a rite of passage for HomeLab enthusiasts. It moves beyond hosting a simple website and teaches you how to manage low-latency media bridges and real-time signaling.

The 5-Minute Quick Start

If you already have Docker and Docker Compose ready, you can launch a basic instance almost instantly. This initial setup uses self-signed certificates. It’s perfect for local testing, though your browser will flag a security warning until you add a real domain.

1. Clone the Official Repository

git clone https://github.com/jitsi/docker-jitsi-meet
cd docker-jitsi-meet

2. Configure the Environment

Jitsi includes a template for your environment variables. Copy it and run the provided script to generate unique passwords for the internal communication between containers.

cp env.example .env
./gen-passwords.sh

3. Create Persistent Directories

You need to ensure your settings survive a container restart. Create these folders on your host machine to store configuration data.

mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}

4. Launch the Stack

docker-compose up -d

Navigate to https://localhost:8443 or your server’s IP. Click “Advanced” and “Proceed” to bypass the certificate warning and enter the interface.

Under the Hood: How the Components Interact

Jitsi isn’t just one big application. It is a coordinated symphony of several microservices. Knowing what each part does makes troubleshooting much easier when audio drops or a connection fails.

The Web Container (Nginx)

This is your entry point. It serves the React-based front-end to your browser. It also acts as a reverse proxy, intelligently routing traffic to the other backend components. If you want to change the UI layout or swap the logo, this is where you’ll work.

Prosody (The Signaling Brain)

Jitsi uses XMPP—the same protocol behind the old Jabber chat—to handle signaling. Prosody is the server that manages user presence, chat messages, and session setup. Think of it as the glue that keeps everyone in the same virtual room.

Jicofo (The Focus)

Short for Jitsi Conference Focus, this component manages the media sessions between participants and the bridge. It allocates resources and ensures every attendee is talking to the correct video stream.

JVB (The Heavy Lifter)

The Jitsi Videobridge (JVB) handles the actual video and audio data. Unlike older systems that mixed video on the server and ate up CPU cycles, JVB simply routes video packets. This efficiency allows a modest server to handle dozens of people at once.

Going Production-Ready

A local setup is a great start. However, to use this with friends or colleagues over the web, you need a domain, SSL, and basic security.

1. Automated SSL with Let’s Encrypt

Open your .env file. Update these specific lines to handle HTTPS certificates automatically:

HTTP_PORT=80
HTTPS_PORT=443
PUBLIC_URL=https://meet.yourdomain.com
ENABLE_LETSENCRYPT=1
[email protected]
LETSENCRYPT_DOMAIN=meet.yourdomain.com

2. Locking Down Authentication

By default, anyone with your URL can start a meeting. To prevent unwanted guests from using your bandwidth, enable internal authentication in your .env file:

ENABLE_AUTH=1
AUTH_TYPE=internal

Restart your containers, then create your admin user manually inside the Prosody container:

docker-compose exec prosody prosodyctl --config /config/prosody.cfg.lua register username meet.jitsi password

3. Fixing the “No Video” Firewall Trap

The most common headache for new admins is the “black screen” issue. This usually happens because the required ports are blocked. Ensure your firewall allows these:

  • 80/TCP: Necessary for Let’s Encrypt renewals.
  • 443/TCP: The standard port for the web interface.
  • 10000/UDP: The critical path for video and audio streams.
  • 3478/UDP: Helps clients connect through restrictive NAT setups (STUN).

Optimization and Real-World Tips

Hardware Requirements

You don’t need a beefy 16GB RAM server. JVB is surprisingly light. I have successfully hosted 10-person calls on a VPS with 2GB of RAM and 2 CPU cores (roughly $12/month on DigitalOcean). Your bottleneck will likely be upload bandwidth. Plan for about 2.5 Mbps of outbound speed per 720p HD stream.

Leverage the Mobile Apps

The Jitsi iOS and Android apps are excellent. Don’t bother with the browser on your phone. Simply open the app settings and change the “Server URL” to your own domain. It provides a native experience while staying entirely on your private hardware.

Custom Branding

Make the platform your own. You can override the default UI by mapping a custom interface_config.js file in your ~/.jitsi-meet-cfg/web directory. You can hide the Jitsi logo, change the background colors, or rename the app to match your personal brand.

Monitoring for Lag

If a call gets choppy, check the built-in “speaker stats.” Jitsi includes small connection bars on every participant’s tile. If only one person shows red bars, the issue is their local Wi-Fi, not your server. This makes it easy to debug performance issues on the fly.

Hosting your own communication tools moves the needle on digital sovereignty. Once Jitsi is running, you’ll realize you don’t have to trade privacy for convenience. It requires some initial configuration, but the peace of mind is worth the effort.

Share: