How to install Jitsi Meet with Docker

Short answer

For a fresh Linux server, install Docker Engine and the Compose plugin, download one pinned docker-jitsi-meet release, generate service passwords and configure the public hostname. Create the release's input and writable storage directories, check published ports and image tags, then start the stack. Verify trusted HTTPS and a three-person meeting across different networks before relying on it.

This guide covers a fresh self-hosted Docker installation, with Jitsi serving HTTPS directly on a DNS hostname. The reviewed release is stable-11248-2, published 23 October 2026, at commit 74d3e6edbb275d700d25de71bddc7088a78b1af4. The core stack has web, Prosody, Jicofo and videobridge services, using ghcr.io/jitsi images. [S1][S2]

The selected patch release restores a missing Prosody dependency and corrects Jigasi custom CA handling. For an existing affected installation, use the missing inspect diagnosis or private CA checks and the upgrade workflow instead of rerunning fresh-install password generation. [S1]

The commands were checked against the release files and a local Compose configuration check. We have not deployed this revision on a public server or completed a live meeting. If you already run Jitsi, use the rootless upgrade guide instead of copying this fresh-install recipe over existing files.

Before you start

New to the components? Follow one meeting through Jitsi’s architecture to understand what the web service, signaling components and videobridge each do before investigating a failed check.

  • A Linux host with a supported Docker Engine installation, shell access and sudo. This recipe assumes ordinary rootful Docker Engine without user-namespace remapping; the Jitsi containers themselves run unprivileged. Docker-daemon rootless mode and remapped host IDs need their own volume-permission checks. [S5][S7][S8]
  • Bash, curl, tar and OpenSSL available on the host. The password generator calls OpenSSL. [S4][S13][S15][S16]
  • A hostname such as meet.example.com, with DNS routing to the intended server. Check both A and any AAAA records before requesting a certificate. Follow SSL setup for IPv6 and challenge validation.
  • Enough capacity for your workload; use server requirements to plan it. This article does not establish a universal participant capacity.
  • A fresh target path: /opt/jitsi-meet. If it already exists, stop and inspect your installation before proceeding. For an existing external HTTPS proxy, follow the reverse-proxy guide instead of this direct-HTTPS port setup.

1. Install Docker

Use Docker’s official repository instructions for Ubuntu or Debian, including the Compose plugin. Docker recommends its convenience script for testing and development, so this guide does not pipe that script into a production root shell. [S7]

Check the CLI, Compose plugin and daemon access. The examples use docker compose; if your account requires sudo for Docker access, apply it consistently to Docker commands. Adding a user to the Docker group grants root-level privileges and is an administrator choice. [S8][S10]

Terminal
docker --version
docker compose version
docker info >/dev/null

2. Download one pinned release

Run these Bash commands on the fresh host. mkdir intentionally fails if the target exists. Stop on any error; do not overwrite an existing installation. The archive contains the release files together, rather than mixing a few downloads with another release. [S1][S13][S15][S16]

Terminal
set -e
sudo mkdir /opt/jitsi-meet
sudo chown "$(id -u):$(id -g)" /opt/jitsi-meet
cd /opt/jitsi-meet

RELEASE=stable-11248-2
curl --fail --show-error --silent --location \
  "https://github.com/jitsi/docker-jitsi-meet/archive/refs/tags/${RELEASE}.tar.gz" \
  --output release.tar.gz
tar -xzf release.tar.gz
cd "docker-jitsi-meet-${RELEASE}"

umask 077
cp env.example .env
bash ./gen-passwords.sh
umask 022

The generator fills the internal service passwords in .env and creates .env.bak. Keep both files private. The restrictive umask applies while creating those files; restoring it afterwards lets the later input directories be readable by the container user. Run the generator for this initial setup, not as an upgrade step that silently replaces existing credentials. [S4][S15]

3. Edit .env

Edit the existing .env, preserving its generated passwords and other release settings. Replace the hostname, email and documentation-only IP address below. The CONFIG value matches the new directory created in the next step. [S2][S3]

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

DISABLE_HTTPS=0
ENABLE_HTTP_REDIRECT=1
ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=meet.example.com
LETSENCRYPT_EMAIL=admin@example.com
LETSENCRYPT_ACME_SERVER=letsencrypt
LETSENCRYPT_USE_STAGING=0

JITSI_IMAGE_REPO=ghcr.io/jitsi
JITSI_IMAGE_VERSION=stable-11248-2
JVB_ADVERTISE_IPS=203.0.113.10

Set JVB_ADVERTISE_IPS to the media address reachable by your participants. For a simple public server that is its public IP; NAT and multiple-network deployments need a deliberate address and forwarding plan. Do not wait for a failed third participant to configure it. [S2][S3][S12]

The ACME provider is explicit because the reviewed environment example documents a different default provider. Public HTTP-01 validation needs port 80; this release maps the chosen host HTTP port to container 8000, and host HTTPS to container 8443. See SSL setup and renewal before changing certificate settings. [S2][S3][S6]

4. Create the config folders

For the four core services in this recipe, create the input directories and the mounted writable directories below. Optional recording, SIP and transcription services need their own additional setup. [S2]

Terminal
mkdir -p /opt/jitsi-meet/config/{web/custom-ca,prosody/config,prosody/prosody-plugins-custom,prosody/custom-ca,jicofo/custom-ca,jvb/custom-ca}

sudo install -d -o 1000 -g 1000 -m 0750 \
  /opt/jitsi-meet/config/storage/{web,prosody,transcripts} \
  /opt/jitsi-meet/config/tmp/web-load-test

The writable directories use UID/GID 1000 for the reviewed unprivileged images on this recipe’s standard Docker host. This avoids making storage world-writable. The input folders are separate from persistent service data, and generated runtime files live inside the containers. If you use remapped IDs, ACLs or a rootless Docker daemon, verify the effective mapping instead of assuming numeric ownership is sufficient. [S2][S5][S6][S8][S16]

5. Open the firewall

Plan the public paths before starting. These are the direct-HTTPS example’s ports; retain SSH access on your actual management port and restrict it to your administration source where practical. [S2]

Public port Purpose in this recipe
TCP 80 Built-in HTTP-01 certificate validation and HTTP entry point
TCP 443 HTTPS web and signaling
UDP 10000 Default published videobridge media port

Check cloud firewall rules, any NAT forwarding and the host’s Docker-aware filtering. Published container traffic can bypass ordinary UFW input rules, so ufw allow or ufw enable alone does not establish the exposure you intended. Do not enable a new firewall blindly over SSH. [S2][S9]

Use the ports and firewall guide for network-specific checks and TURN considerations. This base recipe does not deploy a TURN server; users on restricted networks may need one. [S12]

6. Start the stack

From the extracted release directory containing .env, validate the model and inspect only the resolved image names. A full rendered Compose configuration can contain passwords, so do not paste it publicly. [S10]

Terminal
docker compose config --quiet
docker compose config --images

Expect the four core image names to use ghcr.io/jitsi/ and end in :stable-11248-2. Resolve a different tag or registry before starting. Then pull and start the services: [S2][S10][S11]

Terminal
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail 100 web

Built-in ACME runs during web startup; a failed request can stop that startup. Check errors before another attempt. For certificate problems, use certificate diagnostics. If you change environment settings afterwards, use docker compose up -d with the same files to apply them; docker compose restart alone does not update the environment. [S6][S11]

7. Test it properly

First verify the public HTTPS endpoint from another network. Do not disable certificate verification with -k. The command must succeed and the browser must open your expected Jitsi site without a certificate warning. [S13]

Terminal
curl --fail --show-error --silent --output /dev/null \
  --write-out 'HTTP %{http_code}\n' https://meet.example.com/

Then create a temporary meeting and join with three participants on different networks, using devices with the necessary permissions. Two participants can use peer-to-peer mode when it is enabled and succeeds; a two-person success therefore does not establish videobridge connectivity. [S14]

Check that all three can hear and see one another, reconnect, and use screen sharing where their browser supports it. Test the restricted networks your users actually need. If the third participant breaks media, follow videobridge connectivity diagnostics. A valid certificate and running containers are separate checks from a working meeting.

Before wider use, choose who can create meetings and verify that policy with a separate unauthenticated browser. Follow secure-domain authentication or JWT authentication according to your deployment. Do not assume generating internal component passwords establishes your user access policy. [S3]

Customizing without losing changes

In this release, web startup copies /config into /run/web/config, generates the runtime files, then appends supported custom input files. With this recipe’s CONFIG value, use: [S2][S6]

  • /opt/jitsi-meet/config/web/custom-config.js for supported behavior overrides.
  • /opt/jitsi-meet/config/web/custom-interface_config.js for supported interface overrides.

Use custom configuration diagnostics and branding guidance to check the setting you need. Avoid editing generated /run/web/config/config.js as your persistent input. [S6]

Common installation problems

Symptom First check
manifest unknown Resolve image names and confirm the registry and tag match the downloaded release. [S2][S10]
Storage is not writable Check the reported mount and effective container-user permissions; preserve its data. [S5]
Certificate request fails Check DNS, public challenge routing and web logs before retrying. [S6]
HTTPS works but meeting media fails Check advertised media addresses and network paths; test beyond two participants. [S2][S3][S14]
Changed environment setting has no effect Recreate through Compose up with your normal files instead of only restarting. [S11]

Debian and Ubuntu packages

These instructions install Jitsi’s Docker stack, not the native Debian/Ubuntu Jitsi packages. Package paths, service management and certificate automation differ. Use the Ubuntu installation guide for that route; do not mix its host services with this recipe’s port ownership.

Next steps

Open questions and maintenance

We checked the pinned archive, password generation and resolved Compose model locally. These checks do not establish Linux host ownership enforcement, image startup, public CA issuance, real renewal or a complete Jitsi meeting. Those require a suitable server and clients. The revised page is marked source-reviewed, not deployment-tested. Recheck the release, mounts, settings and image availability before a later installation; preserve data and use a maintenance window for existing deployments.

Sources

Reviewed 25 October 2026. Docker source links are pinned to commit 74d3e6edbb275d700d25de71bddc7088a78b1af4.

Written by the Jitsi Help engineering team

Jitsi infrastructure engineers who deploy and run Jitsi Meet servers in production. Last updated . How we write our guides

Stuck on something this page does not cover? Ask a question below. Jitsi Help engineers read every one.

Did this guide work for you?

Something on this page is outdated or wrong?

Frequently asked questions

Which Jitsi Docker release does this guide use?

This revision uses stable-11248-2, reviewed on 25 October 2026. Keep the release files and image tags together. Recheck upstream releases before a later installation; changing an image tag alone is not a complete upgrade procedure.

Why does Docker Jitsi say a storage directory is not writable?

The reviewed images run as an unprivileged user with UID 1000. Create the required persistent storage and temporary directories before starting, and make them writable by that user. Container rootless operation is separate from running the Docker daemon in rootless mode.

Where should I edit Docker Jitsi's configuration?

Use .env and supported input files under CONFIG. In this release, web copies its input into /run/web/config and generates runtime configuration there. Use custom-config.js or custom-interface_config.js for supported persistent overrides rather than editing generated runtime files.

Does a successful two-person call prove the server works?

No. When peer-to-peer mode is enabled and succeeds, a two-person call can avoid the videobridge. Test three participants across different networks, including the networks your users need. A good HTTPS page alone does not verify signaling or media.

Can I use these steps to upgrade an existing Jitsi server?

Use the upgrade guide instead. This recipe creates a fresh installation. Existing deployments need backups, matching release files, preserved passwords and certificate state, plus any required storage migration and a rollback plan.

Discussion

    Stuck, or would rather not do this by hand?

    Deploy it in one click

    A private Jitsi server in your own AWS account with SSL, your domain and optional recording, transcription and JWT. Free 15 minute trial.

    Start free trial

    Talk to a Jitsi engineer

    Setup, fixes, branding, recording, scaling. Tell us what is happening and we reply with a plan and a quote.

    Get expert help

    Related

    Recently updated