- Complete end-user configuration guide for self-hosted Jitsi Meet
- Covers installation, JWT authentication, and Prosody configuration
- Webhook event handling with mod_event_sync setup
- Jibri recording service configuration and finalize script
- Room creation, JWT token management, and security best practices
- Comprehensive troubleshooting with debug commands and solutions
- Performance optimization and scaling considerations
- Migration guidance from Whereby platform
🤖 Generated with Claude Code
14 KiB
Jitsi Meet Integration Configuration Guide
This guide explains how to configure Reflector to use your self-hosted Jitsi Meet installation for video meetings, recording, and participant tracking.
Overview
Jitsi Meet is an open-source video conferencing platform that can be self-hosted. Reflector integrates with Jitsi Meet to:
- Create secure meeting rooms with JWT authentication
- Track participant join/leave events via Prosody webhooks
- Record meetings using Jibri recording service
- Process recordings for transcription and analysis
Requirements
Self-Hosted Jitsi Meet
You need a complete Jitsi Meet installation including:
- Jitsi Meet Web Interface - The main meeting interface
- Prosody XMPP Server - Handles room management and authentication
- Jicofo (JItsi COnference FOcus) - Manages media sessions
- Jitsi Videobridge (JVB) - Handles WebRTC media routing
- Jibri Recording Service - Records meetings (optional but recommended)
System Requirements
- Domain with SSL Certificate - Required for WebRTC functionality
- Prosody mod_event_sync - For webhook event handling
- JWT Authentication - For secure room access control
- Storage Solution - For recording files (local or cloud)
Configuration Variables
Add the following environment variables to your Reflector .env file:
Required Variables
# Jitsi Meet Domain (without https://)
JITSI_DOMAIN=meet.example.com
# JWT Secret for room authentication (generate with: openssl rand -hex 32)
JITSI_JWT_SECRET=your-64-character-hex-secret-here
# Webhook secret for event handling (generate with: openssl rand -hex 16)
JITSI_WEBHOOK_SECRET=your-32-character-hex-secret-here
Optional Variables
# Application identifier (should match Jitsi configuration)
JITSI_APP_ID=reflector
# JWT issuer and audience (should match Jitsi configuration)
JITSI_JWT_ISSUER=reflector
JITSI_JWT_AUDIENCE=jitsi
Installation Steps
1. Jitsi Meet Server Installation
Quick Installation (Ubuntu/Debian)
# Add Jitsi repository
curl -fsSL https://download.jitsi.org/jitsi-key.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/jitsi-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" | sudo tee /etc/apt/sources.list.d/jitsi-stable.list
# Install Jitsi Meet
sudo apt update
sudo apt install jitsi-meet
# Configure SSL certificate
sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
Docker Installation
# Clone Jitsi Docker repository
git clone https://github.com/jitsi/docker-jitsi-meet
cd docker-jitsi-meet
# Copy environment template
cp env.example .env
# Edit configuration
nano .env
# Start services
docker-compose up -d
2. JWT Authentication Setup
Update Prosody Configuration
Edit /etc/prosody/conf.d/your-domain.cfg.lua:
VirtualHost "meet.example.com"
authentication = "token"
app_id = "reflector"
app_secret = "your-jwt-secret-here"
-- Allow anonymous access for guests
c2s_require_encryption = false
admins = { "focusUser@auth.meet.example.com" }
modules_enabled = {
"bosh";
"pubsub";
"ping";
"roster";
"saslauth";
"tls";
"dialback";
"disco";
"carbons";
"pep";
"private";
"blocklist";
"vcard";
"version";
"uptime";
"time";
"ping";
"register";
"admin_adhoc";
"token_verification";
"event_sync"; -- Required for webhooks
}
Configure Jitsi Meet Interface
Edit /etc/jitsi/meet/your-domain-config.js:
var config = {
hosts: {
domain: 'meet.example.com',
muc: 'conference.meet.example.com'
},
// Enable JWT authentication
enableUserRolesBasedOnToken: true,
// Recording configuration
fileRecordingsEnabled: true,
liveStreamingEnabled: false,
// Reflector integration settings
prejoinPageEnabled: true,
requireDisplayName: true
};
3. Webhook Event Configuration
Install Event Sync Module
# Download the module
cd /usr/share/jitsi-meet/prosody-plugins/
wget https://raw.githubusercontent.com/jitsi-contrib/prosody-plugins/main/mod_event_sync.lua
Configure Event Sync
Add to your Prosody configuration:
Component "conference.meet.example.com" "muc"
storage = "memory"
modules_enabled = {
"muc_meeting_id";
"muc_domain_mapper";
"polls";
"event_sync"; -- Enable event sync
}
-- Event sync webhook configuration
event_sync_url = "https://your-reflector-domain.com/v1/jitsi/events"
event_sync_secret = "your-webhook-secret-here"
-- Events to track
event_sync_events = {
"muc-occupant-joined",
"muc-occupant-left",
"jibri-recording-on",
"jibri-recording-off"
}
4. Jibri Recording Setup (Optional)
Install Jibri
# Install Jibri package
sudo apt install jibri
# Create recording directory
sudo mkdir -p /var/recordings
sudo chown jibri:jibri /var/recordings
Configure Jibri
Edit /etc/jitsi/jibri/jibri.conf:
jibri {
recording {
recordings-directory = "/var/recordings"
finalize-script = "/opt/jitsi/jibri/finalize.sh"
}
api {
xmpp {
environments = [{
name = "prod environment"
xmpp-server-hosts = ["meet.example.com"]
xmpp-domain = "meet.example.com"
control-muc {
domain = "internal.auth.meet.example.com"
room-name = "JibriBrewery"
nickname = "jibri-nickname"
}
control-login {
domain = "auth.meet.example.com"
username = "jibri"
password = "jibri-password"
}
}]
}
}
}
Create Finalize Script
Create /opt/jitsi/jibri/finalize.sh:
#!/bin/bash
# Jibri finalize script for Reflector integration
RECORDING_FILE="$1"
ROOM_NAME="$2"
REFLECTOR_API_URL="${REFLECTOR_API_URL:-http://localhost:1250}"
# Prepare webhook payload
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)
PAYLOAD=$(cat <<EOF
{
"room_name": "$ROOM_NAME",
"recording_file": "$RECORDING_FILE",
"recording_status": "completed",
"timestamp": "$TIMESTAMP"
}
EOF
)
# Generate signature
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$JITSI_WEBHOOK_SECRET" | cut -d' ' -f2)
# Send webhook to Reflector
curl -X POST "$REFLECTOR_API_URL/v1/jibri/recording-complete" \
-H "Content-Type: application/json" \
-H "X-Jitsi-Signature: $SIGNATURE" \
-d "$PAYLOAD"
echo "Recording finalization webhook sent for room: $ROOM_NAME"
Make executable:
sudo chmod +x /opt/jitsi/jibri/finalize.sh
5. Restart Services
After configuration changes:
sudo systemctl restart prosody
sudo systemctl restart jicofo
sudo systemctl restart jitsi-videobridge2
sudo systemctl restart jibri
sudo systemctl restart nginx
Room Configuration
Creating Jitsi Rooms
Create rooms with Jitsi platform in Reflector:
curl -X POST "https://your-reflector-domain.com/v1/rooms" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-d '{
"name": "my-jitsi-room",
"platform": "jitsi",
"recording_type": "cloud",
"recording_trigger": "automatic-2nd-participant",
"is_locked": false,
"room_mode": "normal"
}'
Meeting Creation
Meetings automatically use JWT authentication:
curl -X POST "https://your-reflector-domain.com/v1/rooms/my-jitsi-room/meeting" \
-H "Authorization: Bearer $AUTH_TOKEN"
Response includes JWT-authenticated URLs:
{
"id": "meeting-uuid",
"room_name": "reflector-my-jitsi-room-123456",
"room_url": "https://meet.example.com/room?jwt=user-token",
"host_room_url": "https://meet.example.com/room?jwt=moderator-token"
}
Features and Capabilities
JWT Authentication
Reflector automatically generates JWT tokens with:
- Room Access Control - Secure room entry
- User Roles - Moderator vs participant permissions
- Expiration - Configurable token lifetime (default 8 hours)
- Custom Claims - Room-specific metadata
Recording Options
Recording Types:
"none"- No recording"local"- Local Jibri recording"cloud"- Cloud recording (requires external storage)
Recording Triggers:
"none"- Manual recording only"prompt"- Prompt users to start"automatic"- Start immediately"automatic-2nd-participant"- Start when 2nd person joins
Event Tracking
Automatic participant tracking via webhooks:
- Join/leave events update participant counts
- Recording state changes trigger processing
- Real-time meeting analytics
Testing and Verification
Health Check
Test Jitsi webhook integration:
curl "https://your-reflector-domain.com/v1/jitsi/health"
Expected response:
{
"status": "ok",
"service": "jitsi-webhooks",
"timestamp": "2025-01-15T10:30:00.000Z",
"webhook_secret_configured": true
}
JWT Token Testing
Verify JWT generation works:
# Create a test meeting
MEETING=$(curl -X POST "https://your-reflector-domain.com/v1/rooms/test-room/meeting" \
-H "Authorization: Bearer $AUTH_TOKEN" | jq -r '.room_url')
echo "Test meeting URL: $MEETING"
Webhook Testing
Test event webhook manually:
curl -X POST "https://your-reflector-domain.com/v1/jitsi/events" \
-H "Content-Type: application/json" \
-H "X-Jitsi-Signature: test-signature" \
-d '{
"event": "muc-occupant-joined",
"room": "test-room-name",
"timestamp": "2025-01-15T10:30:00.000Z",
"data": {}
}'
Troubleshooting
Common Issues
JWT Authentication Failures
Symptoms: Users cannot join rooms, "Authentication failed" errors
Solutions:
- Verify
JITSI_JWT_SECRETmatches Prosody configuration - Check JWT token hasn't expired (default 8 hours)
- Ensure system clocks are synchronized between servers
- Validate JWT issuer/audience configuration matches
Debug JWT tokens:
# Decode JWT payload
echo "JWT_TOKEN_HERE" | cut -d'.' -f2 | base64 -d | jq
Webhook Events Not Received
Symptoms: Participant counts not updating, no recording events
Solutions:
- Verify
mod_event_syncis loaded in Prosody - Check webhook URL is accessible from Jitsi server
- Validate webhook signature generation
- Review Prosody and Reflector logs
Debug webhook connectivity:
# Test from Jitsi server
curl -v "https://your-reflector-domain.com/v1/jitsi/health"
# Check Prosody logs
sudo tail -f /var/log/prosody/prosody.log
Recording Issues
Symptoms: Recordings not starting, finalize script errors
Solutions:
- Verify Jibri service status:
sudo systemctl status jibri - Check recording directory permissions:
/var/recordings - Validate finalize script execution permissions
- Monitor Jibri logs:
sudo journalctl -u jibri -f
Test finalize script:
sudo -u jibri /opt/jitsi/jibri/finalize.sh "/test/recording.mp4" "test-room"
Meeting Creation Failures
Symptoms: HTTP 500 errors when creating meetings
Solutions:
- Check Reflector logs for JWT generation errors
- Verify all required environment variables are set
- Ensure Jitsi domain is accessible from Reflector
- Test JWT secret configuration
Debug Commands
# Verify Prosody configuration
sudo prosodyctl check config
# Check Jitsi services status
sudo systemctl status prosody jicofo jitsi-videobridge2
# Test JWT generation
curl -X POST "https://your-reflector-domain.com/v1/rooms/test/meeting" \
-H "Authorization: Bearer $TOKEN" -v
# Monitor webhook events
sudo tail -f /var/log/reflector/app.log | grep jitsi
# Check SSL certificates
sudo certbot certificates
Performance Optimization
Scaling Considerations
Single Server Limits:
- ~50 concurrent participants per JVB instance
- ~10 concurrent Jibri recordings
- CPU and bandwidth become bottlenecks
Multi-Server Setup:
- Multiple JVB instances for scaling
- Dedicated Jibri recording servers
- Load balancing for high availability
Resource Monitoring
# Monitor JVB performance
sudo systemctl status jitsi-videobridge2
sudo journalctl -u jitsi-videobridge2 -f
# Check Prosody connections
sudo prosodyctl mod_admin_telnet
> c2s:show()
> muc:rooms()
Security Best Practices
JWT Security
- Use strong, unique secrets (32+ characters)
- Rotate JWT secrets regularly
- Implement proper token expiration
- Never log or expose JWT tokens
Network Security
- Use HTTPS/WSS for all communications
- Implement proper firewall rules
- Consider VPN for server-to-server communication
- Monitor for unauthorized access attempts
Recording Security
- Encrypt recordings at rest
- Implement access controls for recording files
- Regular security audits of file permissions
- Comply with data protection regulations
Migration from Whereby
If migrating from Whereby to Jitsi:
- Parallel Setup - Configure Jitsi alongside existing Whereby
- Room Migration - Update room platform field to "jitsi"
- Test Integration - Verify meeting creation and webhooks
- User Training - Different UI and feature set
- Monitor Performance - Watch for issues during transition
- Cleanup - Remove Whereby configuration when stable
Support and Resources
Jitsi Community Resources
- Documentation: jitsi.github.io/handbook
- Community Forum: community.jitsi.org
- GitHub Issues: github.com/jitsi/jitsi-meet
Professional Support
- 8x8 Commercial Support - Professional Jitsi hosting and support
- Community Consulting - Third-party Jitsi implementation services
Monitoring and Maintenance
- Monitor system resources (CPU, memory, bandwidth)
- Regular security updates for all components
- Backup configuration files and certificates
- Test disaster recovery procedures