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:
dig +short meet.example.comreturns the server’s public IP.- Port 80/tcp is open in the server firewall and the cloud firewall.
- 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.