Jibri (Jitsi Broadcasting Infrastructure) records a meeting by joining it as a hidden participant in a headless Chrome browser, capturing the screen and the audio, and encoding them to MP4 with ffmpeg. That design explains every requirement below: it needs a virtual sound card, real CPU, and a certificate Chrome trusts.
Requirements
- A working Jitsi Docker install. See install Jitsi with Docker.
- 8 GB of RAM if Jibri shares the Jitsi server, or a separate recorder server.
- About 2 CPU cores per concurrent recording.
- The
snd-aloopkernel module on the machine that runs Jibri. - A domain with a valid certificate, strongly recommended.
1. Load the ALSA loopback module
Jibri captures audio from an ALSA loopback device. Check the module is available for the running kernel:
sudo modprobe -n snd-aloop && echo available || echo missing
On AWS, Ubuntu’s linux-aws kernel does not ship it. Install linux-generic, make it the default GRUB entry, update-grub, and reboot once. The full steps are in Jitsi on AWS.
Then configure enough loopback devices and substreams, load the module, and persist it:
echo "options snd-aloop enable=1,1,1 index=0,1,2 pcm_substreams=8" | sudo tee /etc/modprobe.d/jibri-aloop.conf
sudo modprobe snd-aloop
echo snd-aloop | sudo tee /etc/modules-load.d/snd-aloop.conf
2. Enable recording in .env
ENABLE_RECORDING=1
# Pin it. The Jitsi server and every recorder must agree on this domain.
XMPP_RECORDER_DOMAIN=hidden.meet.jitsi
JIBRI_FINALIZE_RECORDING_SCRIPT_PATH=/config/finalize.sh
gen-passwords.sh already set JIBRI_RECORDER_PASSWORD and JIBRI_XMPP_PASSWORD. If you added Jibri to an older .env, run it again or set them by hand.
Only on a server without a real certificate:
IGNORE_CERTIFICATE_ERRORS=1
3. Start with the Jibri overlay
Download jibri.yml from the same release as your compose file and start both:
cd /opt/jitsi-meet
curl -fsSLO https://raw.githubusercontent.com/jitsi/docker-jitsi-meet/stable-11031/jibri.yml
docker compose -f docker-compose.yml -f jibri.yml up -d
docker compose -f docker-compose.yml -f jibri.yml logs -f jibri
In a meeting, a moderator now sees Start recording in the menu.
4. Record several meetings at once
One Jibri records one meeting. To run more, scale the service with a small override file:
# jibri-scale.yml
services:
jibri:
deploy:
replicas: 3
docker compose -f docker-compose.yml -f jibri.yml -f jibri-scale.yml up -d
Compose v2 honours deploy.replicas outside swarm mode. Give the machine about 2 cores and 2 GB of RAM per replica on top of the Jitsi stack, or move recorders to their own server.
5. A dedicated recording server
For regular recording, run Jibri on a separate machine (on AWS, a c5.large for one concurrent recording or a c5.xlarge for two or three). The recorder connects to Prosody on the Jitsi server on port 5222:
- Publish 5222 from the Prosody container on the Jitsi server.
- Allow 5222/tcp in the Jitsi server’s firewall only from the recorder. On AWS, reference the recorder’s security group.
- Use identical
XMPP_RECORDER_DOMAIN,JIBRI_RECORDER_PASSWORDandJIBRI_XMPP_PASSWORDvalues on both machines.
A mismatched recorder domain is invisible until someone presses Record and nothing happens.
6. Upload recordings to S3
Jibri runs the finalize script inside its container, with the finished session folder as the first argument. Keep it tiny and just mark the folder complete:
#!/bin/bash
# /opt/jitsi-meet/config/jibri/finalize.sh (seen as /config/finalize.sh in the container)
[ -n "$1" ] && touch "$1/.ready"
exit 0
A systemd timer on the host then ships only completed sessions and frees the disk:
#!/bin/bash
REC_DIR=/opt/jitsi-meet/config/jibri/recordings
BUCKET=my-recordings-bucket
shopt -s nullglob
for dir in "$REC_DIR"/*/; do
[ -e "${dir}.ready" ] || continue
name=$(basename "$dir")
aws s3 cp "$dir" "s3://$BUCKET/$name/" --recursive --exclude ".ready" --only-show-errors && rm -rf "$dir"
done
Splitting “mark” from “upload” matters: uploading from inside the finalize script blocks Jibri, and a failed upload would otherwise lose the file. Give the instance an IAM role with s3:PutObject on the bucket instead of storing keys on disk.
Troubleshooting
The three failures we see most, each with a fix, are in Jitsi recording not working:
- “Timed out waiting for call page to load”: certificate or network problem.
- Recording starts then stops, or has no audio: snd-aloop missing or too few substreams.
- The Record button does nothing: recorder domain or password mismatch, or no free Jibri.
Prefer it done for you?
On our platform, recording is a one-time $39 feature per server. It installs the kernel fix, sizes the recorder, and uploads every recording to an S3 bucket in your own AWS account. We also set up Jibri on existing servers as a service.