# How to install Jitsi Meet with Docker

> Point a domain at your server, install Docker, download docker-compose.yml and env.example from one pinned docker-jitsi-meet release, generate passwords, set PUBLIC_URL and Let's Encrypt in .env, open 80/tcp, 443/tcp and 10000/udp, then run docker compose up -d. Always test with three people, because two-person calls bypass the videobridge.

Source: https://jitsi.help/guides/install-jitsi-docker/
Updated: September 26, 2026
Publisher: Jitsi Help (https://jitsi.help/)

The Docker setup is the most reliable way to run Jitsi Meet today. Every component (web, Prosody, Jicofo, the videobridge) runs in its own container, upgrades are a tag change, and the whole stack is described by two files you can keep in version control.

This is the same layout our platform deploys on customer servers, pinned to `stable-11031`.

## Before you start

- A Linux server with 2 vCPU and 4 GB of RAM or more. See [server requirements](/guides/jitsi-server-requirements/).
- A public IP address.
- A domain such as `meet.example.com` with an `A` record pointing at that IP. Create it first; Let's Encrypt validates it on the first start.
- SSH access with sudo.

## 1. Install Docker

On Ubuntu or Debian, Docker's convenience script installs Docker Engine and the Compose plugin:

```bash
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER   # log out and back in afterwards
docker compose version
```

## 2. Download one pinned release

Pin a release instead of tracking `latest`. The compose file references image tags, and mixing a compose file from one release with images from another is a common cause of containers that refuse to start.

```bash
sudo mkdir -p /opt/jitsi-meet && sudo chown $USER /opt/jitsi-meet
cd /opt/jitsi-meet

RELEASE=stable-11031
BASE=https://raw.githubusercontent.com/jitsi/docker-jitsi-meet/$RELEASE
curl -fsSLO $BASE/docker-compose.yml
curl -fsSL -o .env $BASE/env.example
curl -fsSLO $BASE/gen-passwords.sh
chmod +x gen-passwords.sh
./gen-passwords.sh
```

`gen-passwords.sh` fills in the internal component passwords (`JICOFO_AUTH_PASSWORD`, `JVB_AUTH_PASSWORD` and the rest) in `.env`. Never reuse the example values.

## 3. Edit .env

Open `.env` and set at least these values:

```ini
CONFIG=/opt/jitsi-meet/config
HTTP_PORT=80
HTTPS_PORT=443
PUBLIC_URL=https://meet.example.com
TZ=UTC

# Always send http:// to https://. Camera and microphone only work on HTTPS.
ENABLE_HTTP_REDIRECT=1

ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=meet.example.com
LETSENCRYPT_EMAIL=you@example.com

# Keep images on the same release as the compose file.
JITSI_IMAGE_VERSION=stable-11031
```

If your server is behind NAT and calls with three people fail later, also set:

```ini
JVB_ADVERTISE_IPS=203.0.113.10   # your public IP
```

## 4. Create the config folders

The containers write their generated configuration under `CONFIG`:

```bash
mkdir -p /opt/jitsi-meet/config/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
```

## 5. Open the firewall

On the server (ufw) and in your cloud provider's firewall or security group:

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw enable
```

Forgetting 10000/udp in the cloud security group, while opening it in ufw, is the classic mistake. Both layers have to allow it.

## 6. Start the stack

```bash
cd /opt/jitsi-meet
docker compose up -d
docker compose ps
docker compose logs -f web
```

On the first start the web container requests the Let's Encrypt certificate. When the log settles, open `https://meet.example.com`.

## 7. Test it properly

Open a room in **three** browsers or devices, not two. Two participants connect peer to peer and never touch the videobridge, so a broken 10000/udp path only shows up when the third person joins.

Check that:

- All three see and hear each other.
- The padlock shows a valid certificate.
- Screen sharing works.

## Customizing without losing changes

The containers regenerate `config.js` and `interface_config.js` on every restart. Put your changes in these files instead, and they are appended on start:

- `config/web/custom-config.js` for behavior, for example `config.disableInviteFunctions = true;`
- `config/web/custom-interface_config.js` for branding, for example `interfaceConfig.APP_NAME = "Acme Meet";`

See [white-label branding](/guides/jitsi-white-label-branding/) for a full example.

## Next steps

- Lock down who can create rooms: [password authentication](/guides/jitsi-secure-domain-authentication/) or [JWT tokens](/guides/jitsi-jwt-authentication/).
- Add [recording with Jibri](/guides/jitsi-recording-jibri/) or [transcription with Vosk](/guides/jitsi-transcription-vosk/).
- Plan upgrades: [upgrading Docker Jitsi safely](/guides/upgrade-jitsi-docker/).

## Frequently asked questions

### Which Jitsi Docker release should I use?

Use the latest stable-NNNNN tag from the docker-jitsi-meet releases page and pin it. Download the compose file from that same tag and set JITSI_IMAGE_VERSION to it, because the compose file and the image tags must come from the same release.

### Do I need to open port 4443?

No. Current releases carry media over 10000/udp, with 443/tcp for the web app and signalling. Port 4443 was a TCP media fallback in old releases and is not needed today.

### Where does Docker Jitsi store its configuration?

In the folder set by CONFIG in .env, which defaults to ~/.jitsi-meet-cfg. The containers generate config files there on first start and regenerate most of them on every restart, so persistent changes go in the custom-*.js files or in .env.

### How long does a Docker install take?

About 20 to 30 minutes by hand once DNS has propagated. Most of the time goes into DNS, firewall rules and certificate issuance rather than Docker itself.


---

Jitsi Help is an independent service. It is not affiliated with, endorsed by or sponsored by 8x8, Inc. or the Jitsi project. Jitsi and Jitsi Meet are trademarks of 8x8, Inc., used here only to describe the software we host and support.
