Jitsi Meet Video Conferencing Installation

Jitsi Meet is a free, open-source WebRTC-based video conferencing platform that you can self-host for unlimited participants and meetings without per-user licensing costs. This guide covers installing Jitsi Meet on Linux, configuring authentication, recording with Jibri, and scaling for larger deployments.

Prerequisites

  • Ubuntu 22.04 LTS (recommended - best official support)
  • 4 GB RAM minimum (8 GB recommended for 50+ concurrent users)
  • A domain name pointing to your server (required for HTTPS/WebRTC)
  • Ports open: 80, 443 (TCP), 10000 (UDP for media)
  • Root or sudo access

Installing Jitsi Meet

The official installation script handles everything:

# Update the system
sudo apt-get update && sudo apt-get upgrade -y

# Add the Jitsi repository
curl https://download.jitsi.org/jitsi-key.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/jitsi-key.gpg
echo "deb [signed-by=/usr/share/keyrings/jitsi-key.gpg] https://download.jitsi.org stable/" \
  | sudo tee /etc/apt/sources.list.d/jitsi-stable.list

# Set your domain name before installing
sudo hostname meet.example.com

# Install Jitsi Meet
sudo apt-get update
sudo apt-get install -y jitsi-meet

# During installation you'll be prompted for:
# 1. Hostname (use your FQDN: meet.example.com)
# 2. SSL certificate (choose "Generate a new self-signed certificate" for now)

After installation, obtain a Let's Encrypt certificate:

# Get a proper TLS certificate
sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

# Enter your email address when prompted
# This replaces the self-signed cert and configures auto-renewal

Open required firewall ports:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp  # Jitsi Videobridge media traffic
sudo ufw allow 4443/tcp   # Jitsi Videobridge fallback (TCP tunneling)

Access Jitsi Meet at https://meet.example.com.

Post-Installation Configuration

Key configuration files:

/etc/jitsi/meet/meet.example.com-config.js  # Client-side config
/etc/prosody/conf.d/meet.example.com.cfg.lua # XMPP server config
/etc/jitsi/jicofo/jicofo.conf               # Conference focus config
/etc/jitsi/videobridge/jvb.conf             # Videobridge config

Edit the client config for common settings:

// /etc/jitsi/meet/meet.example.com-config.js
var config = {
    hosts: {
        domain: 'meet.example.com',
        muc: 'conference.meet.example.com'
    },

    // Lobby - waiting room before joining
    lobbyRooms: true,

    // Hide conference subject from anonymous users
    // requireDisplayName: true,

    // Start muted by default
    startWithAudioMuted: false,
    startWithVideoMuted: false,

    // Resolution
    constraints: {
        video: {
            height: {ideal: 720, max: 1080, min: 180}
        }
    },

    // Disable analytics/tracking
    analytics: {
        disabled: true
    },

    // Enable end-to-end encryption (e2ee)
    e2eeLabels: {
        e2ee: 'Video Bridge Encryption',
    },

    // Prejoin page (shows before joining a conference)
    prejoinConfig: {
        enabled: true
    }
};

Restart services after config changes:

sudo systemctl restart prosody jicofo jitsi-videobridge2

Enabling Authentication

By default, anyone can create a meeting room. Enable authentication to control who can start rooms:

# Edit Prosody config
sudo nano /etc/prosody/conf.d/meet.example.com.cfg.lua

Change the authentication type:

-- Find this section and change:
VirtualHost "meet.example.com"
    authentication = "internal_hashed"   -- Change from "anonymous"

-- Add a new virtual host for guest access (optional)
-- Allows authenticated users to create rooms, guests can join
VirtualHost "guest.meet.example.com"
    authentication = "anonymous"
    c2s_require_encryption = false

Update the Jitsi Meet client config:

// /etc/jitsi/meet/meet.example.com-config.js
var config = {
    // Uncomment for guest domain
    // hosts: {
    //     anonymousdomain: 'guest.meet.example.com',
    // },
    // ...
};

Update Jicofo config:

sudo nano /etc/jitsi/jicofo/jicofo.conf
jicofo {
  authentication {
    enabled = true
    type = XMPP
    login-url = "meet.example.com"
  }
}

Create user accounts:

# Add users who can create rooms
sudo prosodyctl register alice meet.example.com SecurePassword123
sudo prosodyctl register bob meet.example.com SecurePassword456

# List registered users
sudo prosodyctl user list meet.example.com

# Remove a user
sudo prosodyctl deluser [email protected]

Restart services:

sudo systemctl restart prosody jicofo

Customizing the Interface

Custom logo and title:

# Replace the logo
sudo cp your-logo.png /usr/share/jitsi-meet/images/watermark.svg

# Edit the title in interface config
sudo nano /usr/share/jitsi-meet/interface_config.js
// interface_config.js
var interfaceConfig = {
    APP_NAME: 'MyCompany Meet',
    SHOW_JITSI_WATERMARK: false,
    SHOW_WATERMARK_FOR_GUESTS: false,
    DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/your-logo.png',
    MOBILE_APP_PROMO: false,
    NATIVE_APP_NAME: 'MyCompany Meet',

    // Toolbar buttons to show
    TOOLBAR_BUTTONS: [
        'microphone', 'camera', 'desktop', 'fullscreen',
        'hangup', 'chat', 'raisehand', 'tileview',
        'videobackgroundblur', 'etherpad', 'settings',
        'videoquality', 'security'
    ],
};

Custom CSS:

sudo nano /usr/share/jitsi-meet/css/all.css
# Or create a custom file and reference it in head.html

Recording with Jibri

Jibri (Jitsi Broadcasting Infrastructure) records or live-streams meetings to YouTube. It requires a separate machine (or VM) because it launches a Chrome browser to capture the meeting:

# On the Jibri server (Ubuntu 22.04)
# Install Chrome
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" \
  | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt-get update && sudo apt-get install -y google-chrome-stable

# Install Jibri
sudo apt-get install -y jibri

# Create snd kernel module for virtual audio
echo "snd-aloop" | sudo tee -a /etc/modules
sudo modprobe snd-aloop

# Configure Jibri
sudo nano /etc/jitsi/jibri/jibri.conf
// /etc/jitsi/jibri/jibri.conf
jibri {
    id = ""  # Auto-generated
    single-use-mode = false

    api {
        http {
            external-api-port = 2222
            internal-api-port = 3333
        }
        xmpp {
            environments = [{
                name = "meet.example.com"
                xmpp-server-hosts = ["meet.example.com"]
                xmpp-domain = "meet.example.com"
                control-muc {
                    domain = "internal.auth.meet.example.com"
                    room-name = "JibriBrewery"
                    nickname = "jibri-recorder"
                }
                control-login {
                    domain = "auth.meet.example.com"
                    username = "jibri"
                    password = "JibriPassword123"
                }
                call-login {
                    domain = "recorder.meet.example.com"
                    username = "recorder"
                    password = "RecorderPassword123"
                }
                strip-from-room-domain = "conference."
            }]
        }
    }

    recording {
        recordings-directory = /srv/recordings
        finalize-script = /path/to/finalize.sh  # Optional post-processing
    }

    streaming {
        rtmp-allow-list = [".*"]   # Allow all RTMP destinations
    }
}

Create Jibri users in Prosody on the Jitsi Meet server:

sudo prosodyctl register jibri auth.meet.example.com JibriPassword123
sudo prosodyctl register recorder recorder.meet.example.com RecorderPassword123
sudo systemctl enable --now jibri

Scaling with Jitsi Videobridge

Each Jitsi Videobridge (JVB) handles media routing. Add additional JVBs to handle more concurrent users:

# On additional JVB server
sudo apt-get install -y jitsi-videobridge2

# Configure to connect to your Jitsi Meet XMPP server
sudo nano /etc/jitsi/videobridge/jvb.conf
videobridge {
    ice {
        udp {
            port = 10000
        }
    }
    apis {
        xmpp-client {
            configs {
                shard {
                    domain = "meet.example.com"
                    hostname = "meet.example.com"
                    username = "jvb"
                    password = "YourJVBPassword"
                    muc_jids = "[email protected]"
                    muc_nickname = "jvb-2"
                    disable_certificate_verification = false
                }
            }
        }
    }
}

Jicofo automatically load-balances between available JVBs using the Octo protocol.

Docker Deployment

For containerized deployment:

git clone https://github.com/jitsi/docker-jitsi-meet.git
cd docker-jitsi-meet

cp env.example .env
nano .env  # Set CONFIG, PUBLIC_URL, ENABLE_AUTH, etc.

# Generate passwords
./gen-passwords.sh

# Create config directories
mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}

# Start
docker compose up -d

# The docker-compose includes: web, prosody, jicofo, jvb

Troubleshooting

Can't connect to meeting (WebRTC error):

# Verify UDP port 10000 is reachable from the internet
# Test from an external machine:
nc -u your-server-ip 10000

# Check if Videobridge is running
sudo systemctl status jitsi-videobridge2
sudo journalctl -u jitsi-videobridge2 -f

Audio/video not working:

# Check if TURN server is needed (for users behind symmetric NAT)
# Add COTURN server to config.js:
# p2p: { stunServers: [{urls: "stun:stun.example.com:3478"}] },
# ...

Authentication not working:

sudo journalctl -u prosody -f
# Check Prosody logs for XMPP errors

# Verify config.js has the right domain
grep -i "auth\|anon" /etc/prosody/conf.d/meet.example.com.cfg.lua

Jibri recording fails to start:

sudo journalctl -u jibri -f
# Common: Chrome crash (need --no-sandbox), permissions on recordings dir
sudo chmod 777 /srv/recordings

Conclusion

Jitsi Meet provides a fully open-source, self-hosted video conferencing solution with no per-user fees or time limits. The quick-install package handles most of the complexity, and the combination of Prosody for XMPP signaling, Jitsi Videobridge for media routing, and optional Jibri for recording covers most team communication needs. For reliable production operation, ensure UDP port 10000 is accessible, use Let's Encrypt for TLS, and scale by adding additional JVB nodes as your concurrent user count grows.