Links
- Source
- https://github.com/jitsi/jitsi-meet
- Main example Jitsi Meet instance
- https://meet.jit.si/
- NixOS manual
- https://nixos.org/manual/nixos/stable/#module-services-jitsi-meet
- Handbook and self-hosting guide
- https://jitsi.github.io/handbook/docs/devops-guide/
- Secure Domain setup?
- https://jitsi.github.io/handbook/docs/devops-guide/secure-domain/
- Jibri (Jitsi BRoadcasting Infrastructure) - Used for streaming or recording?
- https://github.com/jitsi/jibri
- Jigasi (allows regular SIP clients to join)
- https://github.com/jitsi/jigasi
NixOS configuration
Here’s a basic configuration I’m trying out for Jitsi Meet on NixOS.
Probably the key thing to notice is the secureDomain.enable = true; option.
{
# https://nixos.org/manual/nixos/stable/#module-services-jitsi-meet
services.jitsi-meet = {
enable = true;
hostName = "jitsi.jmm.example";
prosody.lockdown = true;
# "secureDomain" is what's going to prevent anonymous people from starting a meeting on your server
secureDomain = {
enable = true;
# authentication?
};
# TODO: see "passwordFile" option:
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/services/web-apps/jitsi-meet.nix
config = {
enableWelcomePage = false;
prejoinPageEnabled = true;
defaultLang = "en";
};
interfaceConfig = {
# See https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js
SHOW_JITSI_WATERMARK = false;
SHOW_WATERMARK_FOR_GUESTS = false;
};
# Jibri is for recording?
jibri.enable = true;
};
services.jitsi-videobridge = {
# You can’t enable this unless you also configure nat.localAddress.
# nat.publicAddress = "XX.XX.XXX.XX";
openFirewall = true;
};
networking.firewall.allowedTCPPorts = [
80
443
];
nixpkgs.config.permittedInsecurePackages = [
# 2026-02-23: This is due to an issue with libolm used in Matrix
# and Jitsi Meet being vulnerable to a side-channel attack. I’m
# not sharing secrets over Jitsi Meet, so I’ll allow this.
"jitsi-meet-1.0.8792"
];
# Also configure your certificates:
security.acme = {
acceptTerms = true;
defaults.email = "joshwhatever@email.example";
certs = {
"someserver.jmm.example" = {
extraDomainNames = [
"jitsi.jmm.example"
];
};
};
};
}
Authentication
- The main documentation for this is in the handbook: https://jitsi.github.io/handbook/docs/devops-guide/secure-domain
I struggled for a long time figuring out how to get authentication working in Jitsi Meet.
The FSF has a Jitsi Meet instance for members, and you’re supposed to be able to authenticate with your XMPP account, but I just never saw an option or prompt for a username and password.
By default, Jitsi Meet won’t prompt at all.
In NixOS, you need to add services.jitsi-meet.secureDomain.enable = true; which sets up requiring authentication (see https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/services/web-apps/jitsi-meet.nix).
If your server is “jitsi.jmm.example”, this will also set up authentication domains like “auth.jitsi.jmm.example” and “guest.jitsi.jmm.example”.
Note: Besides jitsi.jmm.example, you don’t need to and should not set up DNS records or TLS certs for these subdomains; they’re basically internal to prosody.
It’s important to know that Jitsi Meet essentially sets up XMPP using Prosody as a server.
The way you’ll authenticate is with an XMPP account, which you add using prosodyctl.
If you enable secureDomains, you may need to restart prosody to pick up the changes.
Restart using systemctl restart prosody.service.
I didn’t do that, and I got a bunch of errors when trying to add users.
You’ll need to add users to authenticate as.
I noticed that in NixOS there’s not only /etc/prosody/prosody.cfg.lua, but also that for prosody.service the environment variable PROSODY_CONFIG=/run/prosody/prosody.cfg.lua.
The handbook will tell you to add a user using something like:
prosodyctl register alice jitsi.jmm.example somepassworddzqX2wjSfmbOGn5Y
but it’s weird to provide your password via command line, so I think instead you’re better off doing:
prosodyctl adduser alice@jitsi.jmm.example
and then you’ll be prompted for a password and have to re-type it.
I’ll note that some errors I got were:
startup warn Configuration warning: /run/prosody/prosody.cfg.lua:148: Duplicate option 'restrict_room_creation' startup warn Configuration warning: /run/prosody/prosody.cfg.lua:168: Duplicate option 'restrict_room_creation' startup warn Configuration warning: /run/prosody/prosody.cfg.lua:207: Duplicate option 'restrict_room_creation' certmanager error Error indexing certificate directory /run/prosody/certs: cannot open /run/prosody/certs: No such file or directory Error: Creating user failed
startup warn Configuration warning: /etc/prosody/prosody.cfg.lua:148: Duplicate option 'restrict_room_creation' startup warn Configuration warning: /etc/prosody/prosody.cfg.lua:168: Duplicate option 'restrict_room_creation' startup warn Configuration warning: /etc/prosody/prosody.cfg.lua:207: Duplicate option 'restrict_room_creation' The given hostname does not exist in the config
I think the issue was that my domain wasn’t initially configured with authentication = "internal_hashed".
When I did configure it, I think I forgot to restart prosody.service to pick up the changes.
Issues
-
2026-02-23: After setting it up it seemed like when trying to do a one-on-one meeting with a Firefox+macOS that there wasn’t any audio or video, but once you added a third person the video showed up.
My intuition here is that in a one-on-one scenario, it’s trying to do WebRTC directly vs with a group it’ll do a video bridge. Not sure why direct WebRTC fails with certain clients or if I can opt to always use a video bridge.- How do you debug WebRTC in Firefox again?
- 2026-02-23: On Firefox+macOS it seemed like the microphone didn’t work (although it did with Chrome).
-
Need to figure out how to record stuff with Jibri on
possibly the same server.- It turns out that that isn’t recommended: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-requirements
- Do I need to set up a TURN server like coTURN? Is there an easy way to switch credentials or should I risk exposing a long-lived secret?
-
Do I set
nat.localAddressif it’s a public server? - Do I need to disable the firewall if forwarding connections?