# 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.

Difficulty: Intermediate\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

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.

> **Note**
>
> The Jitsi handbook also documents a Debian/Ubuntu package install. On that path, the older secure-domain login is now marked deprecated and the documented replacement is token authentication through Keycloak. The Docker setup used here has a built-in user login, which makes it the simpler choice for a single 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](/guides/install-docker-ubuntu) or [Install Docker on Debian](/guides/install-docker-debian).
- A non-root user with `sudo` rights ([Secure a new Linux server](/guides/secure-a-new-linux-server)).
- A domain name such as `meet.example.com` with 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.

```bash
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 verbose
```

Docker 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:

```bash
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)
ls
```

The 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:

```bash
unzip -q stable-*
mv jitsi-docker-jitsi-meet-* meet
cd meet
```

## Step 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:

```bash
cp env.example .env
./gen-passwords.sh
chmod 600 .env
grep -c "PASSWORD=." .env
```

The 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:

```env
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=admin@example.com
ENABLE_AUTH=1
ENABLE_GUESTS=1
AUTH_TYPE=internal
```

What these do:

- `HTTP_PORT` and `HTTPS_PORT` publish the web container on the standard ports, which Let's Encrypt requires.
- `PUBLIC_URL` must be the real address users open.
- `JVB_ADVERTISE_IPS` tells 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=1` with `AUTH_TYPE=internal` makes Jitsi ask for a username and password before a room is created; `ENABLE_GUESTS=1` still lets invited people join without an account.
- `TZ` sets the time zone for logs; replace `UTC` with your own zone, for example `Europe/Istanbul`.

> **Tip**
>
> Let's Encrypt limits how many certificates you can request. If DNS is not ready yet, start once with `ENABLE_LETSENCRYPT` commented out, check that everything else works, then enable it.

## 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:

```bash
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:

```bash
docker compose up -d
docker compose ps
docker compose logs -f web
```

All 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:

```bash
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 `.env` file 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:

```bash
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 -d
```

To 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.

```bash
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 -d
```

Replace `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](/guides/install-mattermost) or [Matrix Synapse and Element](/guides/install-matrix-synapse).
- Learn the Compose commands used here in [Docker Compose basics](/guides/docker-compose-basics).
- Read the official [Jitsi handbook](https://jitsi.github.io/handbook/docs/devops-guide/) for TURN, scaling with more videobridges and recording.
- Compare servers for video meetings on the [Jitsi hosting](/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.

---

Source: <https://hyperdc.com/guides/tutorials/install-jitsi-meet>\
Updated: 2026-10-09
