GuidesChat and emailJitsi Meet video meetings

Host video meetings with Jitsi Meet

Jitsi Meet on Debian 13, video meetings in the browser on your own server, where only your users can start a meeting and guests join with a link, with free certificates and no calls to outside services.

Tested on Jitsi Meet 2.0.11248 with Prosody 13.0 on Debian 13 (trixie) on a Melonslab server Updated September 27, 2026

Recommended server for this guide

VC-S Micro · 2 vCPU · 8 GB Memory · 250 GB Storage

Month to month, no lock-in 7-day money-back guarantee

€7.99/mo

Deploy now
On this page

What you will set up

Jitsi Meet is a video meeting service, like Zoom or Google Meet, that runs on your own server. People join in the browser from a link, with nothing to install.

A Jitsi server is several programs working together: a web server, nginx, serves the page; Prosody passes messages between participants; the videobridge carries the sound and video of every meeting; and coturn helps people on networks that block the videobridge. This guide uses Jitsi's own Debian packages, which install cleanly on Debian 13 with Debian's own Prosody and Java and run as ordinary system services. Jitsi's Docker setup needs root Docker, which opens ports past ufw. Give Jitsi a server of its own: it takes over ports 80 and 443 for nginx.

Out of the box, anyone who finds your server can start a meeting on it. Step 4 changes that, so only accounts you create can start one, and anyone with the link can join once it has started.

Every step below was run on a fresh Melonslab VC-P Alloy (2 vCPU, 8 GB) with Debian 13:

  • Jitsi Meet installed in about 90 seconds and got a Let's Encrypt certificate for its name by itself.
  • A guest who opened a meeting alone was told to wait for a moderator. Once a user had logged in and started the meeting, the guest joined it. A wrong password was refused.
  • Two participants in Chromium, with test camera and microphone, sent and received video through the videobridge on UDP port 10000, and also directly to each other, and through coturn.
  • The page made no requests to other sites, and the server no longer asks Jitsi's own STUN server for its address (step 6).
  • An upgrade from the previous Jitsi release kept every change, and everything came back by itself after a reboot.

With two people in a meeting, Jitsi's programs used about 700 MB of memory together, most of it in the two Java services.

Before you start

You need:

  • a fresh Melonslab server with Debian 13 and nothing else installed;
  • a name for it, such as meet.example.com, with an A record and an AAAA record pointing at the server. Create them first: the installer asks Let's Encrypt for a certificate straight away.

Set up SSH keys, automatic security updates and ufw as in steps 1 to 4 of the security guide, including the rule for HTTP and HTTPS.

The examples use meet.example.com, 203.0.113.10 for the server's IPv4 address and 2001:db8::10 for its IPv6 address. Replace them throughout.

1. Open the ports

As root:

ufw allow 10000/udp
ufw allow 3478/udp
ufw allow 5349/tcp

The videobridge carries meetings on UDP port 10000. coturn listens on UDP port 3478, and on TCP port 5349 with TLS, for people whose network blocks UDP port 10000. The rules cover IPv4 and IPv6.

2. Add Jitsi's package repository

apt update
apt install -y curl gnupg
curl -fsSL https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmor -o /usr/share/keyrings/jitsi-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" > /etc/apt/sources.list.d/jitsi-stable.list
apt update

The repository is the same for every Debian release. On Debian 13 Jitsi uses Debian's own Prosody 13 and Java 21.

3. Install Jitsi Meet

The installer asks for the server's name, which certificate to use and an email address for Let's Encrypt. Give the answers first, with your own name and address:

cat <<'EOF' | debconf-set-selections
jitsi-videobridge2 jitsi-videobridge/jvb-hostname string meet.example.com
jitsi-meet-web-config jitsi-meet/cert-choice select Let's Encrypt certificates
jitsi-meet-web-config jitsi-meet/email string anna@example.com
jitsi-meet-web-config jitsi-meet/jaas-choice boolean false
EOF
DEBIAN_FRONTEND=noninteractive apt install -y jitsi-meet

The last answer declines a free account on JaaS, 8x8's hosted Jitsi service. The installer downloads acme.sh from GitHub, gets the certificate with it, and adds a cron job that renews it. It ends with an advert for JaaS, which you can ignore. Warnings about the hostname or Could not get FQDN are about a spare self-signed certificate, and are harmless.

Open https://meet.example.com. The page offers to start a meeting, and at this point anyone can.

4. Let only your users start meetings

Jitsi calls this a secure domain. Jitsi's documentation now points to signed tokens instead, which need a login service of your own. A secure domain needs nothing else, and works as described here.

Open /etc/prosody/conf.avail/meet.example.com.cfg.lua. Under VirtualHost "meet.example.com", change the line

    authentication = "jitsi-anonymous" -- do not delete me

to:

    authentication = "internal_hashed"

And add this to the end of the file:

VirtualHost "guest.meet.example.com"
    authentication = "jitsi-anonymous"
    c2s_require_encryption = false

Guests connect to guest.meet.example.com. It is a name inside Prosody only, and needs no DNS record.

Open /etc/jitsi/meet/meet.example.com-config.js. Under hosts:, below the line domain: 'meet.example.com',, add:

        anonymousdomain: 'guest.meet.example.com',

Open /etc/jitsi/jicofo/jicofo.conf, and below the first line, jicofo {, add:

  authentication: {
    enabled: true
    type: XMPP
    login-url: meet.example.com
  }

Restart the services, and create an account for each person who should be able to start meetings. prosodyctl asks for the password twice:

systemctl restart prosody jicofo jitsi-videobridge2
prosodyctl adduser anna@meet.example.com

prosodyctl passwd anna@meet.example.com sets a new password, and prosodyctl deluser anna@meet.example.com removes the account.

5. Hold a meeting

Open https://meet.example.com, enter a name for the meeting and choose Start meeting, then Join meeting. A dialog says Waiting for a moderator…. Choose Log-in, and enter the user name, anna, and the password under User and User password. Choose Login. The meeting starts, and you are its moderator.

Send the address in your browser to the others. They choose Join meeting and are let straight in, without an account. If a guest arrives before you, they see Waiting for a moderator… until you have logged in.

Meetings with two people go directly between the two browsers when they can reach each other. From three people, or when they cannot, everything goes through the videobridge.

6. Keep outside services out

Two settings send something to other services by default:

  • The videobridge asks a STUN server run by Jitsi, meet-jit-si-turnrelay.jitsi.net, for its public address at every start. A Melonslab server has its public addresses on its own network card, so it does not need to ask.
  • Browsers ask the same server for their address in meetings between two people. Your coturn can answer instead.

In /etc/jitsi/videobridge/jvb.conf, delete the three lines of the stun block, so that the end of the file reads:

ice4j {
    harvest {
        mapping {
            aws {
                enabled = false
            }
        }
    }
}

In /etc/jitsi/meet/meet.example.com-config.js, find the line { urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' }, under p2p: and change it to:

            { urls: 'stun:meet.example.com:3478' },

Jitsi also shows people's pictures from Gravatar, a public service, when they enter an email address in their settings, which sends a code made from the address to Gravatar. To switch that off, add this line just below var config = { at the top of the same file:

    gravatar: { disabled: true },

Then restart the videobridge:

systemctl restart jitsi-videobridge2

Changes to config.js reach each browser when it next loads the page.

7. Close the settings files to other users

Several settings files hold the passwords the Jitsi services use with each other, and every user on the server can read them. Make them readable only to root and the service that needs each one:

chmod o-r /etc/jitsi/jicofo/jicofo.conf /etc/jitsi/videobridge/jvb.conf
chgrp prosody /etc/prosody/conf.avail/meet.example.com.cfg.lua
chgrp turnserver /etc/turnserver.conf
chmod 640 /etc/prosody/conf.avail/meet.example.com.cfg.lua /etc/turnserver.conf
systemctl restart prosody coturn jicofo jitsi-videobridge2

8. What is open to the internet

ss -tulpn lists more than you allowed, but ufw keeps the rest closed. From outside, only these answer:

PortFor
22/tcpSSH
80/tcpRedirects to HTTPS, and Let's Encrypt
443/tcpThe meeting page, and the connection each browser keeps to Prosody
10000/udpSound and video through the videobridge
3478/udp, 5349/tcpcoturn, for networks that block UDP port 10000

Prosody's ports 5222, 5269 and 5281 listen on every address but stay closed. The videobridge's own interface on port 8080 listens only on 127.0.0.1. curl -s localhost:8080/metrics | grep sending_video on the server shows how many participants are sending video right now.

Everything works over IPv6 as well: nginx and coturn listen on both addresses, and the videobridge offers browsers both. The meeting page was tested over IPv6 from the server itself; meetings were tested over IPv4.

9. Updates

The automatic updates from the security guide install Debian's security updates, which include nginx, Prosody, Java and coturn. They do not install Jitsi's own packages. Update those yourself, at a time when nobody is in a meeting, as the services restart:

apt update
apt upgrade

An upgrade keeps your changes to the settings files. The certificate renews by itself: /opt/acmesh/.acme.sh/acme.sh --list --home /opt/acmesh/.acme.sh shows when it renews next.

Troubleshooting

Guests see "Waiting for a moderator…" and never get in. Nobody with an account has started the meeting yet. It starts when someone chooses Log-in in the same meeting and logs in.

Logging in says "Incorrect username or password". Enter the name without @meet.example.com. Set a new password with prosodyctl passwd anna@meet.example.com.

You can join a meeting, but nobody sees or hears anyone. UDP port 10000 cannot be reached. Check ufw status for the rules from step 1, and that ss -ulpn | grep 10000 shows the videobridge's java process. With only two people, the meeting may be going directly between the browsers, so try with a third.

The browser warns about the certificate. Let's Encrypt could not reach the server when you installed, usually because the A or AAAA record was missing. Once both point at the server, run /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh anna@example.com meet.example.com.

Nothing works after editing a settings file. A typing error stops a service from starting. systemctl status prosody jicofo jitsi-videobridge2 shows which one. Prosody's log is in /var/log/prosody, and those of jicofo and the videobridge are in /var/log/jitsi.

Run it on your own server

VC-S Micro

€7.99/mo

vCPU
2
Memory
8 GB
Storage
250 GB
Transfer
10 TB
Standard
HDD · RAID 10
  • Full root access
  • Native /64 IPv6
  • RAID-protected storage
  • Malmö, Sweden
  • Month to month, no lock-in
  • 7-day money-back guarantee
All guides