How to install Jitsi Meet with Docker and Let's Encrypt
Run your own Jitsi Meet video conferencing server with the official Docker setup, a Let's Encrypt certificate and logins so only your users can open rooms.
- Intermediate
- 40 min read
- Updated
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13
On this page
- Prerequisites
- Step 1 — Open the firewall ports
- Step 2 — Download the latest release
- Step 3 — Create the .env file and generate passwords
- Step 4 — Set the domain, HTTPS and logins
- Step 5 — Create the configuration folders and start Jitsi
- Step 6 — Create user accounts
- Step 7 — Test a meeting
- Back up and restore
- Update Jitsi Meet
- Troubleshooting
- Calls work with two people but there is no audio or video with three
- The certificate is not issued
- A container keeps restarting after an update
- Anyone can still create rooms without logging in
- Ports 80 or 443 are already in use
- Next steps
Jitsi Meet is an open-source video conferencing platform that runs in the browser and in the Jitsi mobile apps. Running your own server keeps meeting traffic on infrastructure you control and lets you decide who may create rooms. This guide installs Jitsi Meet with the project's official docker-jitsi-meet release on Ubuntu or Debian, gets a certificate from Let's Encrypt, requires a login to start meetings, and shows how to back up, update and troubleshoot the server.
Prerequisites
- A server running Ubuntu 24.04 or 26.04 LTS, or Debian 12 or 13, with Docker Engine and the Compose plugin installed: see Install Docker on Ubuntu or Install Docker on Debian.
- A non-root user with
sudorights (Secure a new Linux server). - A domain name such as
meet.example.comwith an A record (and AAAA record if you use IPv6) pointing to the server's public IP address. - Ports 80 and 443 free on the server. The Jitsi web container serves HTTPS itself in this guide, so do not run another web server on the same machine.
Sizing guidance from the Jitsi handbook:
| Resource | Minimum (official) | Suggested starting point |
|---|---|---|
| CPU | 4 dedicated cores for a basic server | 4 or more dedicated cores; avoid shared CPU |
| RAM | 2 GB for tests or very small meetings, 4 GB for small meetings | 8 GB, the handbook's general suggestion |
| Disk | About 20 GB | 20 GB plus room for logs |
| Network | About 1 Gbit/s is often enough for friends or a small organisation | Measure real throughput and latency before you rely on it |
Video bandwidth adds up quickly: the handbook lists about 500 kbit/s per stream at 360p and about 2.5 Mbit/s at 720p.
Step 1 — Open the firewall ports
Jitsi needs HTTPS for the web app and UDP port 10000 for audio and video. Port 80 is used for the Let's Encrypt challenge.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw enable
sudo ufw status verboseDocker publishes these container ports itself and does not depend on ufw for them, but keeping the rules explicit documents what the server is meant to expose.
Step 2 — Download the latest release
The handbook asks you to use a release download rather than cloning the repository, because the release pins matching image versions. Create a working folder and download the latest release archive from GitHub:
sudo apt install wget unzip
sudo mkdir -p /opt/jitsi
sudo chown $USER:$USER /opt/jitsi
cd /opt/jitsi
wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4)
lsThe file is named after the release tag, for example stable- followed by a number. Unpack it and give the folder a fixed name so the Compose project name stays the same across updates:
unzip -q stable-*
mv jitsi-docker-jitsi-meet-* meet
cd meetStep 3 — Create the .env file and generate passwords
Copy the example configuration and let the included script fill in random passwords for the internal service accounts:
cp env.example .env
./gen-passwords.sh
chmod 600 .env
grep -c "PASSWORD=." .envThe last command counts the password lines that now have a value; it should be greater than zero.
Step 4 — Set the domain, HTTPS and logins
Open .env with an editor (nano .env) and set the following values. Some lines exist already, others are commented out with # and must be uncommented:
HTTP_PORT=80
HTTPS_PORT=443
TZ=UTC
PUBLIC_URL=https://meet.example.com
JVB_ADVERTISE_IPS=203.0.113.10
ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=meet.example.com
LETSENCRYPT_EMAIL[email protected]
ENABLE_AUTH=1
ENABLE_GUESTS=1
AUTH_TYPE=internalWhat these do:
HTTP_PORTandHTTPS_PORTpublish the web container on the standard ports, which Let's Encrypt requires.PUBLIC_URLmust be the real address users open.JVB_ADVERTISE_IPStells the videobridge which public IP to give to clients. Inside Docker the bridge sits behind NAT, and without this setting calls with three or more people often have no audio or video. Use your server's public IPv4 address.ENABLE_AUTH=1withAUTH_TYPE=internalmakes Jitsi ask for a username and password before a room is created;ENABLE_GUESTS=1still lets invited people join without an account.TZsets the time zone for logs; replaceUTCwith your own zone, for exampleEurope/Istanbul.
Step 5 — Create the configuration folders and start Jitsi
The containers run as UID/GID 1000 and refuse to start if their configuration folders are missing or not writable. Create them exactly as the handbook shows:
mkdir -p ~/.jitsi-meet-cfg/{web,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri,transcriber}
mkdir -p ~/.jitsi-meet-cfg/storage/{jibri,prosody,transcripts,web}
mkdir -p ~/.jitsi-meet-cfg/tmp/{web-crontabs,web-load-test}
chmod 777 ~/.jitsi-meet-cfg/storage/{jibri,prosody,transcripts,web}
chmod 777 ~/.jitsi-meet-cfg/tmp/{web-crontabs,web-load-test}Start the stack and watch the web container request the certificate:
docker compose up -d
docker compose ps
docker compose logs -f webAll four core services (web, prosody, jicofo, jvb) should show as running. Press Ctrl+C to stop following the log once the certificate has been issued.
Step 6 — Create user accounts
Users are stored in the Prosody container. Create one account for each person who may start meetings; meet.jitsi is the internal XMPP domain of the Docker setup, not your public domain:
docker compose exec prosody prosodyctl --config /run/prosody/config/prosody.cfg.lua register alice meet.jitsi 'a-long-unique-password'The command prints nothing when it succeeds. To remove an account, run the same command with unregister alice meet.jitsi instead of register.
Step 7 — Test a meeting
Open https://meet.example.com in a browser. The certificate should be valid (a padlock with no warning). Enter a room name and click Start meeting; Jitsi asks you to log in as the host. Use the account from Step 6.
Then join the same room from a phone on mobile data and from a third device. A call with three participants is the real test, because it is the first case where all media goes through the videobridge on UDP port 10000.
Back up and restore
Everything that is not in the images lives in two places:
- the
.envfile in/opt/jitsi/meet(domain settings and the generated service passwords), - the configuration folder
~/.jitsi-meet-cfg(generated config, certificates and the Prosody user database).
Create a dated archive of both while the stack is stopped:
cd /opt/jitsi/meet
docker compose down
sudo mkdir -p /opt/backups
sudo tar czf /opt/backups/jitsi-$(date +%F).tar.gz -C / opt/jitsi/meet/.env -C $HOME .jitsi-meet-cfg
docker compose up -dTo restore on a new server, install Docker, download the same release (Step 2), extract the archive so that .env returns to /opt/jitsi/meet and .jitsi-meet-cfg to the admin user's home, and run docker compose up -d. Copy backups off the server as well.
Update Jitsi Meet
Each docker-jitsi-meet release pins a tested set of image versions, so updating means switching to the new release folder. Read the release notes on GitHub first and take a backup.
cd /opt/jitsi
wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4)
unzip -q -o stable-NEW_NUMBER
cp meet/.env jitsi-docker-jitsi-meet-*/.env
cd meet
docker compose down
cd ..
mv meet meet-previous
mv jitsi-docker-jitsi-meet-* meet
cd meet
docker compose pull
docker compose up -dReplace stable-NEW_NUMBER with the file name you just downloaded. Compare the new env.example with your .env and copy over any new settings you want. The handbook notes that when you come from a release older than stable-11146, you keep your configuration folder but must create the new storage and tmp folders from Step 5 before starting. Delete meet-previous once the new version works.
Troubleshooting
Calls work with two people but there is no audio or video with three
Two-person calls can run peer to peer; three or more always go through the videobridge. Check that UDP port 10000 is open in every firewall on the path, and that JVB_ADVERTISE_IPS contains the server's public IP. After changing .env, run docker compose up -d to recreate the containers.
The certificate is not issued
Run docker compose logs web and read the Let's Encrypt messages. The usual causes are a DNS record that does not point to this server yet, port 80 blocked or used by another program, or the Let's Encrypt rate limit after repeated attempts. Fix the cause and restart with docker compose restart web.
A container keeps restarting after an update
Since release stable-11146 the containers are hardened and need the storage and tmp folders from Step 5 with the permissions shown there. Create them, then run docker compose up -d again and check docker compose logs.
Anyone can still create rooms without logging in
The authentication settings are applied when the containers are created. Make sure ENABLE_AUTH=1 and AUTH_TYPE=internal are uncommented in .env, then run docker compose up -d --force-recreate.
Ports 80 or 443 are already in use
Another web server is running on the host. Stop it (sudo systemctl disable --now nginx or caddy), or run Jitsi behind that proxy: keep the web container on local ports, set ENABLE_LETSENCRYPT=0 and proxy the domain to the container's HTTPS port with WebSocket support.
Next steps
- Add a team chat next to your meetings with Mattermost or Matrix Synapse and Element.
- Learn the Compose commands used here in Docker Compose basics.
- Read the official Jitsi handbook for TURN, scaling with more videobridges and recording.
- Compare servers for video meetings on the Jitsi hosting page.
Frequently asked questions
How many participants can one Jitsi server handle?
The Jitsi project gives no fixed number. It depends on CPU, bandwidth and video quality: the handbook lists roughly 200 kbit/s per stream at 180p, 500 kbit/s at 360p and 2.5 Mbit/s at 720p. For large meetings Jitsi recommends adding more videobridges rather than one very large server.
Can guests join without an account?
Yes. With ENABLE_AUTH=1 and ENABLE_GUESTS=1 only registered users can start a room, and anyone with the link can join once the host is there.
Why does this guide use Docker instead of the Debian packages?
Both are official. With the packages, the simple secure-domain login is marked deprecated in the Jitsi handbook and the documented replacement is token authentication with Keycloak. The Docker setup has built-in user logins (AUTH_TYPE=internal) and keeps updates to a single release download.
Can I record meetings?
Recording uses a separate component, Jibri. Each simultaneous recording needs its own Jibri instance with at least 8 GB of RAM at 1280x720, and the handbook advises against running Jibri on the same server as Jitsi Meet.
Can I run Jitsi Meet behind my existing Caddy or Nginx?
Yes, but then the web container must not take ports 80 and 443. Keep HTTP_PORT and HTTPS_PORT on local ports, turn off ENABLE_LETSENCRYPT and proxy the domain to the HTTPS port with WebSocket support. Port 10000/udp must still reach the videobridge directly.
Sources
- jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker
- raw.githubusercontent.com/jitsi/handbook/master/docs/devops-guide/d…
- raw.githubusercontent.com/jitsi/docker-jitsi-meet/master/env.example
- jitsi.github.io/handbook/docs/devops-guide/devops-guide-requirements
- jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart
- jitsi.github.io/handbook/docs/devops-guide/secure-domain
- jitsi.github.io/handbook/docs/devops-guide/authentication