> Source: https://meetrix.io/blogs/setup-jibri-jitsi-meet-recording-ubuntu/
> Markdown copy of that page. Cite the URL above, not this file.

Development

# How to Set Up Jibri for Jitsi Meet Recording and Streaming on Ubuntu 22.04

[By Hiruna Kumara](https://meetrix.io/blogs/authors/hiruna-kumara/) • July 17, 2026 • 11 min read

## What is Jibri?

Jibri (Jitsi Broadcasting Infrastructure) is the component that gives a self-hosted Jitsi Meet server its recording and live streaming buttons. It works in a fairly blunt but reliable way: it joins the conference as a hidden participant, renders the meeting in a Chrome instance running on a virtual framebuffer, and captures that screen with ffmpeg. The output either lands on disk as a file recording or gets pushed to an RTMP endpoint such as YouTube Live.

Because it captures a full Chrome session, one Jibri instance handles exactly one recording at a time, and it wants its own machine (or VM) with nothing else competing for the display and audio devices. That is the main thing to plan around before you start.

This guide walks through the full setup on Ubuntu 22.04: preparing your existing Jitsi Meet server (Prosody, Jicofo, and the web config), then installing and configuring Jibri itself, and finally shipping the finished recordings to S3.

## Prerequisites

Before you start

-   A working Jitsi Meet deployment (this guide uses `meet.example.com` - replace it with your domain everywhere).
-   Root or sudo access to both the Jitsi server and the Jibri machine.
-   A separate Ubuntu 22.04 machine or VM for Jibri with at least 4 vCPUs and 8 GB of RAM. Recording is CPU-hungry; undersized Jibris produce choppy video.
-   Network access from the Jibri machine to the Jitsi server on port 5222 (XMPP) and 443.

If you have not deployed Jitsi Meet yet, set that up first - our [Jitsi Meet on AWS guide](https://meetrix.io/blogs/setup-jitsi-meet-aws-dev-guide/) covers it end to end.

## How Jitsi Meet recording works behind the scenes

Three services on your existing Jitsi server need small changes so Jibri can join meetings without showing up as a participant:

-   **Prosody** - the XMPP server every Jitsi component talks through. It gets a hidden MUC (chat room service) where Jibri instances wait for work, plus a hidden virtual host for the account Jibri uses inside meetings.
-   **Jicofo** - the conference focus. It gets told where that hidden MUC (the "brewery") lives, so it can grab an idle Jibri when someone presses record.
-   **Jitsi Meet web config** - gets the recording and streaming buttons enabled, and learns to hide the recorder account from the participant list.

## Step 1 - Configure Prosody

Open your Prosody host config on the Jitsi server:

```bash
sudo nano /etc/prosody/conf.avail/meet.example.com.cfg.lua
```

Make sure the conference MUC component is present (it normally is on any working Jitsi install):

```lua
Component "conference.meet.example.com" "muc"
    modules_enabled = { "muc_mam" }
```

Then add the internal MUC component and the recorder virtual host at the end of the file. The internal MUC is where Jibri instances register themselves; the recorder host holds the account Jibri uses for the hidden Chrome session:

```lua
-- internal muc component, meant to enable pools of jibri and jigasi clients
Component "internal.auth.meet.example.com" "muc"
    modules_enabled = {
        "ping";
    }
    storage = "memory"
    muc_room_cache_size = 1000

VirtualHost "recorder.meet.example.com"
    modules_enabled = {
        "ping";
    }
    authentication = "internal_plain"
```

Reload Prosody and create the two accounts Jibri will authenticate with - one for control traffic, one for joining the call:

```bash
sudo systemctl reload prosody
sudo prosodyctl register jibri auth.meet.example.com JibriPassword
sudo prosodyctl register recorder recorder.meet.example.com RecorderPassword
```

Pick real passwords

Replace `JibriPassword` and `RecorderPassword` with strong values - you will need the same two passwords again in `jibri.conf` in Step 5.

## Step 2 - Configure Jicofo

Point Jicofo at the brewery MUC so it knows where to find idle Jibri instances. On current Jitsi packages this lives in `jicofo.conf`:

```bash
sudo nano /etc/jitsi/jicofo/jicofo.conf
```

Add a `jibri` block inside the top-level `jicofo` block:

```hocon
jicofo {
  jibri {
    brewery-jid = "JibriBrewery@internal.auth.meet.example.com"
    pending-timeout = 90 seconds
  }
}
```

Restart Jicofo:

```bash
sudo systemctl restart jicofo
```

## Step 3 - Enable recording in the Jitsi Meet config

Edit the web config for your deployment:

```bash
sudo nano /etc/jitsi/meet/meet.example.com-config.js
```

Set the following properties:

```javascript
fileRecordingsEnabled: true,   // enables the "Start recording" button
liveStreamingEnabled: true,    // enables "Start live stream" (RTMP/YouTube)
hiddenDomain: 'recorder.meet.example.com',
```

`hiddenDomain` is what keeps the recorder account invisible - anyone logged in from that domain joins silently and never appears in the participant list.

## Step 4 - Install Jibri on the Ubuntu 22.04 machine

Everything from here on happens on the dedicated Jibri machine, not the Jitsi server.

### ALSA loopback module

Jibri captures audio through the ALSA loopback kernel module. On Ubuntu 22.04 it ships in the extra modules package:

```bash
sudo apt update
sudo apt install linux-modules-extra-$(uname -r)
echo "snd_aloop" | sudo tee -a /etc/modules
sudo modprobe snd_aloop
lsmod | grep snd_aloop
```

If the last command prints a `snd_aloop` line, audio capture is ready. On cloud images the package name can differ - AWS instances want `linux-modules-extra-aws` for example.

### ffmpeg and supporting packages

The ffmpeg build in the Ubuntu 22.04 repos already includes x11 capture support, so the stock package is fine:

```bash
sudo apt install ffmpeg wget gnupg curl unzip alsa-utils icewm xdotool \
  xserver-xorg-input-void xserver-xorg-video-dummy
```

### Google Chrome and ChromeDriver

Install Chrome from Google's repository:

```bash
curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt update
sudo apt install google-chrome-stable
```

ChromeDriver must match the installed Chrome version. Google now distributes it through the Chrome for Testing endpoints (the old `chromedriver.storage.googleapis.com` URL stopped updating at Chrome 114, which is a common trap in older guides):

```bash
CHROME_VERSION=$(google-chrome --version | awk '{print $3}')
wget -N "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chromedriver-linux64.zip"
unzip chromedriver-linux64.zip
sudo mv -f chromedriver-linux64/chromedriver /usr/local/bin/chromedriver
sudo chmod 0755 /usr/local/bin/chromedriver
chromedriver --version
```

Silence Chrome's "automated software" warning bar, which would otherwise appear in every recording:

```bash
sudo mkdir -p /etc/opt/chrome/policies/managed
echo '{ "CommandLineFlagSecurityWarningsEnabled": false }' | sudo tee /etc/opt/chrome/policies/managed/managed_policies.json
```

### Install the Jibri package

Add the Jitsi repository and install Jibri along with Java 11, which current Jibri builds require:

```bash
curl -sL 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
sudo apt update
sudo apt install openjdk-11-jre-headless jibri
```

Give the jibri user access to the audio and video devices:

```bash
sudo usermod -aG adm,audio,video,plugdev jibri
```

## Step 5 - Configure jibri.conf

Modern Jibri reads a HOCON config at `/etc/jitsi/jibri/jibri.conf` (the JSON `config.json` you may remember from older guides is deprecated). Open it:

```bash
sudo nano /etc/jitsi/jibri/jibri.conf
```

Use this as the full config, swapping in your domain and the two passwords from Step 1:

```hocon
jibri {
  recording {
    recordings-directory = "/srv/recordings"
    finalize-script = "/srv/finalize_recording.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-instance-1"
          }
          control-login {
            domain = "auth.meet.example.com"
            username = "jibri"
            password = "JibriPassword"
          }
          call-login {
            domain = "recorder.meet.example.com"
            username = "recorder"
            password = "RecorderPassword"
          }

          strip-from-room-domain = "conference."
          usage-timeout = 0

          // set to true if your Jitsi server uses a self-signed certificate
          trust-all-xmpp-certs = false
        }
      ]
    }
  }
}
```

Two details worth calling out. `room-name = "JibriBrewery"` must match the `brewery-jid` you set in Jicofo. And `trust-all-xmpp-certs = true` replaces the old hack of patching `JibriSelenium.kt` and recompiling the jar just to accept a self-signed certificate - do not follow guides that still recommend rebuilding Jibri for that.

Create the recordings directory and hand it to the jibri user:

```bash
sudo mkdir -p /srv/recordings
sudo chown jibri:jibri /srv/recordings
```

## Step 6 - Start Jibri and run a test recording

Restart the Jitsi-side services once more, then enable and start Jibri:

```bash
# on the Jitsi server
sudo systemctl restart prosody jicofo jitsi-videobridge2

# on the Jibri machine
sudo systemctl enable --now jibri
sudo journalctl -u jibri -f
```

In the journal you want to see Jibri connect to both XMPP hosts and join the brewery. Then open a meeting on your Jitsi instance, press **Start recording**, talk for half a minute, stop it, and check `/srv/recordings` on the Jibri machine for an mp4.

Jibri recordings get large quickly. To share one, cut it down with the [video trimmer](https://meetrix.io/features/video-trimmer/) or shrink it with the [video compressor](https://meetrix.io/features/video-compressor/), both of which run in the browser.

## Uploading recordings to S3

The `finalize-script` runs after every recording completes, which makes it the natural place to ship files off the box. A minimal S3 uploader (requires the AWS CLI and an instance role or credentials with write access to the bucket):

```bash
#!/bin/bash
RECORDINGS_DIR=$1

aws s3 cp --recursive ${RECORDINGS_DIR} s3://your-recordings-bucket

if [ -d "$RECORDINGS_DIR" ]; then
    rm -r ${RECORDINGS_DIR}
fi

exit 0
```

Save it as `/srv/finalize_recording.sh` and make it executable:

```bash
sudo chmod +x /srv/finalize_recording.sh && sudo chown jibri:jibri /srv/finalize_recording.sh
```

For Dropbox instead of S3, Jitsi Meet has a built-in integration: create a Dropbox app, then add its key under `dropbox:` in your `meet.example.com-config.js` with the redirect URI `https://meet.example.com/static/oauth.html`. Users then pick Dropbox when they start a recording.

## Running Jibri with Docker

If your Jitsi deployment runs on [docker-jitsi-meet](https://github.com/jitsi/docker-jitsi-meet), skip the manual install above - the project ships a ready Jibri container. Set the Jibri variables in your `.env` (they map to the same Prosody accounts from Step 1) and start the stack with the overlay file:

```bash
docker compose -f docker-compose.yml -f jibri.yml up -d
```

The host still needs the `snd_aloop` module loaded, since the container captures audio through the host kernel.

## Troubleshooting common Jibri failures

-   **"Recording failed to start" in the meeting UI:** Jicofo cannot find a Jibri in the brewery. Check that `brewery-jid` in `jicofo.conf` and `control-muc` in `jibri.conf` use the same room and domain, and watch `journalctl -u jibri -f` for XMPP login errors (wrong password from Step 1 is the classic cause).
-   **Recording starts, then dies within seconds:** usually a Chrome vs ChromeDriver version mismatch (re-run the ChromeDriver install after any Chrome update) or a certificate problem - set `trust-all-xmpp-certs = true` when testing with self-signed certs. On an internal network there is a second certificate check in the Chrome session as well, covered in [Deploying Jibri in a Private LAN](https://meetrix.io/blogs/deploying-jibri-in-a-private-lan/).
-   **Video records but audio is missing:**`snd_aloop` is not loaded. Run `lsmod | grep snd_aloop`, and remember cloud kernels need their own extra-modules package (e.g. `linux-modules-extra-aws`).
-   **Second recording refuses to start:** that is by design - one Jibri handles one session. Add more Jibri machines with unique `nickname` values pointed at the same brewery.

## Skip the manual setup: Jitsi Meet with recording, pre-configured

Everything above is what we automate in our Marketplace images. If you would rather launch a Jitsi Meet server where Jibri, the hidden domains, and the recording pipeline are already wired up and supported, these deploy in a few minutes:

![Jitsi Meet on AWS Marketplace](https://meetrix.io/blog-images/paas-dev-guides/setup-jitsi-meet-on-aws/setup-jitsi-meet-on-aws-image.png)

Jitsi Meet on AWS Marketplace

Pre-configured Jitsi Meet AMIs supported by Meetrix, sized from 50 to 500 concurrent users, with recording variants that include Jibri out of the box.

[100-user server with recording](https://aws.amazon.com/marketplace/pp/prodview-b4us3agprvuim)[250-user server with recording](https://aws.amazon.com/marketplace/pp/prodview-jxsppdgm4elq4)[Browse all Meetrix products](https://aws.amazon.com/marketplace/seller-profile?id=62b53dd8-45d0-4b50-a654-bd6993167486)

![Jitsi Meet on Google Cloud Marketplace](https://meetrix.io/blog-images/paas-dev-guides/jitsi-meet-gcp/jitsi-meet-gcp-image.png)

Jitsi Meet on Google Cloud Marketplace

The same Jitsi Meet stack published for Google Cloud - every size from 50 to 500 users is also available in a recording variant with Jibri included.

[100-user server with recording](https://console.cloud.google.com/marketplace/product/meetrix-public/jitsi-meet-100-users-recording)[250-user server with recording](https://console.cloud.google.com/marketplace/product/meetrix-public/jitsi-meet-250-users-recording)[Browse all Meetrix products](https://console.cloud.google.com/marketplace/browse?filter=partner:Meetrix%20Pte%20Ltd&ref=meetrix.io)

There is also a full walkthrough of the AWS recording AMI in our [Jitsi Meet with recordings developer guide](https://meetrix.io/blogs/setup-jitsi-meet-with-recordings-developer-guide/).

## Conclusion

A working Jibri setup comes down to four things lining up: the hidden MUC and recorder host in Prosody, the brewery JID in Jicofo, matching credentials in `jibri.conf`, and a Jibri machine whose Chrome, ChromeDriver, and ALSA loopback are all healthy. Once those agree, the record button in Jitsi Meet just works, and scaling to more concurrent recordings is only a matter of cloning the Jibri machine.

## Frequently Asked Questions

Can Jitsi Meet record meetings without Jibri?

Not on the server side. Jibri is the official recording and streaming component for self-hosted Jitsi Meet. Participants can use browser or OS screen recorders locally, but for a Dropbox or file recording button inside the meeting, you need a working Jibri.

What does the Component "internal.auth" "muc" line in Prosody do?

It creates a hidden multi-user chat service that only internal components can reach. Jibri instances join a room there (the brewery) and Jicofo picks an idle one from that room whenever a user presses record. Regular meeting participants never see this MUC.

How many recordings can one Jibri instance handle at a time?

Exactly one. Each recording launches a full Chrome session plus ffmpeg, so one Jibri equals one concurrent recording or stream. To support more, run several Jibri machines pointed at the same brewery MUC and Jicofo will load-balance between them.

Can I install Jibri on the same server as Jitsi Meet?

You can, but it is only sensible for testing. Recording eats about 4 vCPUs and 8 GB of RAM on its own, and Chrome plus ffmpeg will fight your videobridge for CPU. In production, give Jibri its own machine or VM.

Does Jibri work with Docker?

Yes. The official docker-jitsi-meet project ships a jibri.yml overlay, so you can add a Jibri container to a dockerized deployment with one extra compose file. See the Docker section above for the command.

Why does my recording stop a few seconds after it starts?

The three usual causes are a Chrome and ChromeDriver version mismatch, a self-signed certificate that Jibri refuses (set trust-all-xmpp-certs = true), or the snd\_aloop ALSA module not being loaded. Check journalctl -u jibri -f while starting a recording to see which one you are hitting.

## Deploy Jitsi Meet with Recording in Minutes

Launch a production-ready Jitsi Meet server with Jibri recording already configured, using a pre-built Meetrix AMI on AWS.

[Get Started on AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-b4us3agprvuim)

Meetrix Store

Jitsi Meet

Self-hosted video calls for 50 to 500 users

[Deploy it](https://meetrix.io/store/jitsi-meet/)

Meetrix Store New

Deploy what this guide covers, pre-configured.

-    [Jitsi Meet Self-hosted video calls for 50 to 500 users](https://meetrix.io/store/jitsi-meet/)
-    [Coturn TURN/STUN for WebRTC, no per-minute relay fees](https://meetrix.io/store/coturn/)
-    [Mattermost Team chat, a self-hosted Slack alternative](https://meetrix.io/store/mattermost/)
-    [RustDesk Remote desktop AMI, a TeamViewer alternative](https://meetrix.io/store/rustdesk/)
-    [Listmonk Newsletters with no per-subscriber fees](https://meetrix.io/store/listmonk/)
-    [Supabase Postgres, Auth, Storage and Realtime, self-hosted](https://meetrix.io/store/supabase/)

[Browse all products](https://meetrix.io/store/)
