Skip to content
Jitsi.help

Set up Let's Encrypt SSL for Jitsi Meet

Updated By the Jitsi Help engineering team

Short answer

On Docker, set ENABLE_LETSENCRYPT=1, LETSENCRYPT_DOMAIN and LETSENCRYPT_EMAIL in .env, make sure the domain's A record points at the server and port 80 is reachable from the internet, then start the stack. The web container issues and renews the certificate itself. Most failures are DNS not pointing yet, port 80 blocked, or hitting Let's Encrypt's rate limit by retrying.

Jitsi Meet has to be served over HTTPS with a certificate browsers trust, or cameras and microphones simply do not work. The Docker web container can get and renew a free Let’s Encrypt certificate on its own; it only needs DNS and port 80 in order.

The built-in Let’s Encrypt setup

In .env:

HTTP_PORT=80
HTTPS_PORT=443
PUBLIC_URL=https://meet.example.com
ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=meet.example.com
LETSENCRYPT_EMAIL=you@example.com
ENABLE_HTTP_REDIRECT=1

Before starting:

  1. dig +short meet.example.com returns the server’s public IP.
  2. Port 80/tcp is open in the server firewall and the cloud firewall.
  3. Nothing else on the host is listening on port 80 or 443.

Then docker compose up -d and follow docker compose logs -f web until the certificate is issued. Renewal runs automatically inside the web container.

Test against staging first

Let’s Encrypt limits how many certificates you can get for the same domain in a week. While you are still fixing DNS or firewalls, use the staging environment:

LETSENCRYPT_USE_STAGING=1

Browsers will not trust a staging certificate, but a successful staging run proves the setup. Remove the line and restart to get the real one.

Using your own certificate

For a wildcard or corporate certificate, disable Let’s Encrypt and drop the files in place:

ENABLE_LETSENCRYPT=0
cp fullchain.pem /opt/jitsi-meet/config/web/keys/cert.crt
cp privkey.pem   /opt/jitsi-meet/config/web/keys/cert.key
docker compose restart web

cert.crt must contain the full chain, not only the leaf certificate, or some clients will reject it.

Behind a reverse proxy

If Nginx, Traefik or Caddy already owns ports 80 and 443 on the host:

DISABLE_HTTPS=1
ENABLE_LETSENCRYPT=0
ENABLE_HTTP_REDIRECT=0
HTTP_PORT=8000
PUBLIC_URL=https://meet.example.com

The proxy terminates TLS and forwards to http://127.0.0.1:8000. It must pass WebSocket upgrades for /xmpp-websocket and /colibri-ws/. For Nginx:

location / {
  proxy_pass http://127.0.0.1:8000;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
}

Audio and video still flow straight to the videobridge on 10000/udp. Do not try to route media through the web proxy.

IP address only, no domain

Without a domain there is no trusted certificate. The stack serves a self-signed one, every visitor sees a warning, and headless clients such as Jibri refuse to connect unless you set IGNORE_CERTIFICATE_ERRORS=1 for them. A cheap domain is worth it.

When it fails

See Let’s Encrypt failed on Jitsi for the error messages and fixes. On our platform, a custom domain with a trusted certificate is included free on every server, and DNS is checked before a certificate is requested so you never burn through the rate limit.

Frequently asked questions

Does Jitsi work without HTTPS?

Not for real meetings. Browsers only allow camera and microphone access on secure pages, so plain HTTP shows an unsupported browser or permission error. Set ENABLE_HTTP_REDIRECT=1 so anyone typing http:// lands on the HTTPS site.

How do I use my own SSL certificate with Docker Jitsi?

Set ENABLE_LETSENCRYPT=0 and place the certificate and key as cert.crt and cert.key in the keys folder under the web config directory, then restart the web container. Include the full chain in cert.crt.

Can I run Jitsi behind Nginx, Traefik or Caddy?

Yes. Terminate TLS at the proxy, set DISABLE_HTTPS=1 and ENABLE_LETSENCRYPT=0 in .env, proxy to the web container's HTTP port, and make sure WebSocket upgrades are forwarded. Media still goes directly to 10000/udp on the videobridge, not through the proxy.

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