Loading nixos/modules/services/web-apps/jitsi-meet.nix +159 −19 Original line number Diff line number Diff line Loading @@ -169,6 +169,15 @@ in off if you want to configure it manually. ''; }; excalidraw.enable = mkEnableOption (lib.mdDoc "Excalidraw collaboration backend for Jitsi"); excalidraw.port = mkOption { type = types.port; default = 3002; description = lib.mdDoc ''The port which the Excalidraw backend for Jitsi should listen to.''; }; secureDomain.enable = mkEnableOption (lib.mdDoc "Authenticated room creation"); }; config = mkIf cfg.enable { Loading @@ -192,41 +201,118 @@ in roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" admins = { "focus@auth.${cfg.hostName}" } ''; } { domain = "internal.${cfg.hostName}"; domain = "breakout.${cfg.hostName}"; name = "Jitsi Meet Breakout MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" admins = { "focus@auth.${cfg.hostName}" } ''; } { domain = "internal.auth.${cfg.hostName}"; name = "Jitsi Meet Videobridge MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' storage = "memory" admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" } ''; #-- muc_room_cache_size = 1000 } { domain = "lobby.${cfg.hostName}"; name = "Jitsi Meet Lobby MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" ''; } ]; extraModules = [ "pubsub" "smacks" "speakerstats" "external_services" "conference_duration" "end_conference" "muc_lobby_rooms" "muc_breakout_rooms" "av_moderation" "muc_hide_all" "muc_meeting_id" "muc_domain_mapper" "muc_rate_limit" "limits_exception" "persistent_lobby" "room_metadata" ]; extraModules = [ "pubsub" "smacks" ]; extraPluginPaths = [ "${pkgs.jitsi-meet-prosody}/share/prosody-plugins" ]; extraConfig = lib.mkMerge [ (mkAfter '' extraConfig = lib.mkMerge [ (mkAfter '' Component "focus.${cfg.hostName}" "client_proxy" target_address = "focus@auth.${cfg.hostName}" Component "speakerstats.${cfg.hostName}" "speakerstats_component" muc_component = "conference.${cfg.hostName}" Component "conferenceduration.${cfg.hostName}" "conference_duration_component" muc_component = "conference.${cfg.hostName}" Component "endconference.${cfg.hostName}" "end_conference" muc_component = "conference.${cfg.hostName}" Component "avmoderation.${cfg.hostName}" "av_moderation_component" muc_component = "conference.${cfg.hostName}" Component "metadata.${cfg.hostName}" "room_metadata_component" muc_component = "conference.${cfg.hostName}" breakout_rooms_component = "breakout.${cfg.hostName}" '') (mkBefore '' muc_mapper_domain_base = "${cfg.hostName}" cross_domain_websocket = true; consider_websocket_secure = true; unlimited_jids = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" } '') ]; virtualHosts.${cfg.hostName} = { enabled = true; domain = cfg.hostName; extraConfig = '' authentication = "anonymous" authentication = ${if cfg.secureDomain.enable then "\"internal_hashed\"" else "\"jitsi-anonymous\""} c2s_require_encryption = false admins = { "focus@auth.${cfg.hostName}" } smacks_max_unacked_stanzas = 5 smacks_hibernation_time = 60 smacks_max_hibernated_sessions = 1 smacks_max_old_sessions = 1 av_moderation_component = "avmoderation.${cfg.hostName}" speakerstats_component = "speakerstats.${cfg.hostName}" conference_duration_component = "conferenceduration.${cfg.hostName}" end_conference_component = "endconference.${cfg.hostName}" c2s_require_encryption = false lobby_muc = "lobby.${cfg.hostName}" breakout_rooms_muc = "breakout.${cfg.hostName}" room_metadata_component = "metadata.${cfg.hostName}" main_muc = "conference.${cfg.hostName}" ''; ssl = { cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; Loading @@ -237,7 +323,7 @@ in enabled = true; domain = "auth.${cfg.hostName}"; extraConfig = '' authentication = "internal_plain" authentication = "internal_hashed" ''; ssl = { cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; Loading @@ -252,6 +338,14 @@ in c2s_require_encryption = false ''; }; virtualHosts."guest.${cfg.hostName}" = { enabled = true; domain = "guest.${cfg.hostName}"; extraConfig = '' authentication = "anonymous" c2s_require_encryption = false ''; }; }; systemd.services.prosody = mkIf cfg.prosody.enable { preStart = let Loading Loading @@ -317,6 +411,20 @@ in ''; }; systemd.services.jitsi-excalidraw = mkIf cfg.excalidraw.enable { description = "Excalidraw collaboration backend for Jitsi"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment.PORT = toString cfg.excalidraw.port; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.jitsi-excalidraw}/bin/jitsi-excalidraw-backend"; Restart = "on-failure"; Group = "jitsi-meet"; }; }; services.nginx = mkIf cfg.nginx.enable { enable = mkDefault true; virtualHosts.${cfg.hostName} = { Loading Loading @@ -345,12 +453,23 @@ in locations."=/external_api.js" = mkDefault { alias = "${pkgs.jitsi-meet}/libs/external_api.min.js"; }; locations."=/_api/room-info" = { proxyPass = "http://localhost:5280/room-info"; extraConfig = '' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; ''; }; locations."=/config.js" = mkDefault { alias = overrideJs "${pkgs.jitsi-meet}/config.js" "config" (recursiveUpdate defaultCfg cfg.config) cfg.extraConfig; }; locations."=/interface_config.js" = mkDefault { alias = overrideJs "${pkgs.jitsi-meet}/interface_config.js" "interfaceConfig" cfg.interfaceConfig ""; }; locations."/socket.io/" = mkIf cfg.excalidraw.enable { proxyPass = "http://127.0.0.1:${toString cfg.excalidraw.port}"; proxyWebsockets = true; }; }; }; Loading Loading @@ -390,13 +509,24 @@ in }; }; services.jitsi-meet.config = recursiveUpdate (mkIf cfg.excalidraw.enable { whiteboard = { enabled = true; collabServerBaseUrl = "https://${cfg.hostName}"; }; }) (mkIf cfg.secureDomain.enable { hosts.anonymousdomain = "guest.${cfg.hostName}"; }); services.jitsi-videobridge = mkIf cfg.videobridge.enable { enable = true; xmppConfigs."localhost" = { userName = "jvb"; domain = "auth.${cfg.hostName}"; passwordFile = "/var/lib/jitsi-meet/videobridge-secret"; mucJids = "jvbbrewery@internal.${cfg.hostName}"; mucJids = "jvbbrewery@internal.auth.${cfg.hostName}"; disableCertificateVerification = true; }; }; Loading @@ -409,16 +539,26 @@ in userName = "focus"; userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret"; componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret"; bridgeMuc = "jvbbrewery@internal.${cfg.hostName}"; bridgeMuc = "jvbbrewery@internal.auth.${cfg.hostName}"; config = mkMerge [{ jicofo.xmpp.service.disable-certificate-verification = true; jicofo.xmpp.client.disable-certificate-verification = true; #} (lib.mkIf cfg.jibri.enable { } (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) { } (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) { jicofo.jibri = { brewery-jid = "JibriBrewery@internal.${cfg.hostName}"; brewery-jid = "JibriBrewery@internal.auth.${cfg.hostName}"; pending-timeout = "90"; }; }) (lib.mkIf cfg.secureDomain.enable { jicofo = { authentication = { enabled = "true"; type = "XMPP"; login-url = cfg.hostName; }; xmpp.client.client-proxy = "focus.${cfg.hostName}"; }; })]; }; Loading @@ -430,7 +570,7 @@ in xmppDomain = cfg.hostName; control.muc = { domain = "internal.${cfg.hostName}"; domain = "internal.auth.${cfg.hostName}"; roomName = "JibriBrewery"; nickname = "jibri"; }; Loading pkgs/servers/jitsi-excalidraw/default.nix 0 → 100644 +40 −0 Original line number Diff line number Diff line { lib , buildNpmPackage , fetchFromGitHub , nodejs , python3 }: buildNpmPackage rec { pname = "jitsi-excalidraw-backend"; version = "17"; src = fetchFromGitHub { owner = "jitsi"; repo = "excalidraw-backend"; rev = "x${version}"; hash = "sha256-aQePkVA8KRL06VewiD0ePRpj88pAItcV7B2SBnRRtCs="; }; npmDepsHash = "sha256-BJqjaqTeg5i+ECGMuiBYVToK2i2XCOVP9yeDFz6nP4k="; nativeBuildInputs = [ python3 ]; installPhase = '' mkdir -p $out/share cp -r {node_modules,dist} $out/share ''; postFixup = '' makeWrapper ${nodejs}/bin/node $out/bin/jitsi-excalidraw-backend \ --add-flags dist/index.js \ --chdir $out/share ''; meta = with lib; { description = "Excalidraw collaboration backend for Jitsi"; homepage = "https://github.com/jitsi/excalidraw-backend"; license = licenses.mit; maintainers = with maintainers; [ camillemndn ]; }; } pkgs/top-level/all-packages.nix +2 −0 Original line number Diff line number Diff line Loading @@ -26552,6 +26552,8 @@ with pkgs; jicofo = callPackage ../servers/jicofo { }; jitsi-excalidraw = callPackage ../servers/jitsi-excalidraw { }; jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { }; jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { }; Loading
nixos/modules/services/web-apps/jitsi-meet.nix +159 −19 Original line number Diff line number Diff line Loading @@ -169,6 +169,15 @@ in off if you want to configure it manually. ''; }; excalidraw.enable = mkEnableOption (lib.mdDoc "Excalidraw collaboration backend for Jitsi"); excalidraw.port = mkOption { type = types.port; default = 3002; description = lib.mdDoc ''The port which the Excalidraw backend for Jitsi should listen to.''; }; secureDomain.enable = mkEnableOption (lib.mdDoc "Authenticated room creation"); }; config = mkIf cfg.enable { Loading @@ -192,41 +201,118 @@ in roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" admins = { "focus@auth.${cfg.hostName}" } ''; } { domain = "internal.${cfg.hostName}"; domain = "breakout.${cfg.hostName}"; name = "Jitsi Meet Breakout MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" admins = { "focus@auth.${cfg.hostName}" } ''; } { domain = "internal.auth.${cfg.hostName}"; name = "Jitsi Meet Videobridge MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' storage = "memory" admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" } ''; #-- muc_room_cache_size = 1000 } { domain = "lobby.${cfg.hostName}"; name = "Jitsi Meet Lobby MUC"; roomLocking = false; roomDefaultPublicJids = true; extraConfig = '' restrict_room_creation = true storage = "memory" ''; } ]; extraModules = [ "pubsub" "smacks" "speakerstats" "external_services" "conference_duration" "end_conference" "muc_lobby_rooms" "muc_breakout_rooms" "av_moderation" "muc_hide_all" "muc_meeting_id" "muc_domain_mapper" "muc_rate_limit" "limits_exception" "persistent_lobby" "room_metadata" ]; extraModules = [ "pubsub" "smacks" ]; extraPluginPaths = [ "${pkgs.jitsi-meet-prosody}/share/prosody-plugins" ]; extraConfig = lib.mkMerge [ (mkAfter '' extraConfig = lib.mkMerge [ (mkAfter '' Component "focus.${cfg.hostName}" "client_proxy" target_address = "focus@auth.${cfg.hostName}" Component "speakerstats.${cfg.hostName}" "speakerstats_component" muc_component = "conference.${cfg.hostName}" Component "conferenceduration.${cfg.hostName}" "conference_duration_component" muc_component = "conference.${cfg.hostName}" Component "endconference.${cfg.hostName}" "end_conference" muc_component = "conference.${cfg.hostName}" Component "avmoderation.${cfg.hostName}" "av_moderation_component" muc_component = "conference.${cfg.hostName}" Component "metadata.${cfg.hostName}" "room_metadata_component" muc_component = "conference.${cfg.hostName}" breakout_rooms_component = "breakout.${cfg.hostName}" '') (mkBefore '' muc_mapper_domain_base = "${cfg.hostName}" cross_domain_websocket = true; consider_websocket_secure = true; unlimited_jids = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" } '') ]; virtualHosts.${cfg.hostName} = { enabled = true; domain = cfg.hostName; extraConfig = '' authentication = "anonymous" authentication = ${if cfg.secureDomain.enable then "\"internal_hashed\"" else "\"jitsi-anonymous\""} c2s_require_encryption = false admins = { "focus@auth.${cfg.hostName}" } smacks_max_unacked_stanzas = 5 smacks_hibernation_time = 60 smacks_max_hibernated_sessions = 1 smacks_max_old_sessions = 1 av_moderation_component = "avmoderation.${cfg.hostName}" speakerstats_component = "speakerstats.${cfg.hostName}" conference_duration_component = "conferenceduration.${cfg.hostName}" end_conference_component = "endconference.${cfg.hostName}" c2s_require_encryption = false lobby_muc = "lobby.${cfg.hostName}" breakout_rooms_muc = "breakout.${cfg.hostName}" room_metadata_component = "metadata.${cfg.hostName}" main_muc = "conference.${cfg.hostName}" ''; ssl = { cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; Loading @@ -237,7 +323,7 @@ in enabled = true; domain = "auth.${cfg.hostName}"; extraConfig = '' authentication = "internal_plain" authentication = "internal_hashed" ''; ssl = { cert = "/var/lib/jitsi-meet/jitsi-meet.crt"; Loading @@ -252,6 +338,14 @@ in c2s_require_encryption = false ''; }; virtualHosts."guest.${cfg.hostName}" = { enabled = true; domain = "guest.${cfg.hostName}"; extraConfig = '' authentication = "anonymous" c2s_require_encryption = false ''; }; }; systemd.services.prosody = mkIf cfg.prosody.enable { preStart = let Loading Loading @@ -317,6 +411,20 @@ in ''; }; systemd.services.jitsi-excalidraw = mkIf cfg.excalidraw.enable { description = "Excalidraw collaboration backend for Jitsi"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment.PORT = toString cfg.excalidraw.port; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.jitsi-excalidraw}/bin/jitsi-excalidraw-backend"; Restart = "on-failure"; Group = "jitsi-meet"; }; }; services.nginx = mkIf cfg.nginx.enable { enable = mkDefault true; virtualHosts.${cfg.hostName} = { Loading Loading @@ -345,12 +453,23 @@ in locations."=/external_api.js" = mkDefault { alias = "${pkgs.jitsi-meet}/libs/external_api.min.js"; }; locations."=/_api/room-info" = { proxyPass = "http://localhost:5280/room-info"; extraConfig = '' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; ''; }; locations."=/config.js" = mkDefault { alias = overrideJs "${pkgs.jitsi-meet}/config.js" "config" (recursiveUpdate defaultCfg cfg.config) cfg.extraConfig; }; locations."=/interface_config.js" = mkDefault { alias = overrideJs "${pkgs.jitsi-meet}/interface_config.js" "interfaceConfig" cfg.interfaceConfig ""; }; locations."/socket.io/" = mkIf cfg.excalidraw.enable { proxyPass = "http://127.0.0.1:${toString cfg.excalidraw.port}"; proxyWebsockets = true; }; }; }; Loading Loading @@ -390,13 +509,24 @@ in }; }; services.jitsi-meet.config = recursiveUpdate (mkIf cfg.excalidraw.enable { whiteboard = { enabled = true; collabServerBaseUrl = "https://${cfg.hostName}"; }; }) (mkIf cfg.secureDomain.enable { hosts.anonymousdomain = "guest.${cfg.hostName}"; }); services.jitsi-videobridge = mkIf cfg.videobridge.enable { enable = true; xmppConfigs."localhost" = { userName = "jvb"; domain = "auth.${cfg.hostName}"; passwordFile = "/var/lib/jitsi-meet/videobridge-secret"; mucJids = "jvbbrewery@internal.${cfg.hostName}"; mucJids = "jvbbrewery@internal.auth.${cfg.hostName}"; disableCertificateVerification = true; }; }; Loading @@ -409,16 +539,26 @@ in userName = "focus"; userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret"; componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret"; bridgeMuc = "jvbbrewery@internal.${cfg.hostName}"; bridgeMuc = "jvbbrewery@internal.auth.${cfg.hostName}"; config = mkMerge [{ jicofo.xmpp.service.disable-certificate-verification = true; jicofo.xmpp.client.disable-certificate-verification = true; #} (lib.mkIf cfg.jibri.enable { } (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) { } (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) { jicofo.jibri = { brewery-jid = "JibriBrewery@internal.${cfg.hostName}"; brewery-jid = "JibriBrewery@internal.auth.${cfg.hostName}"; pending-timeout = "90"; }; }) (lib.mkIf cfg.secureDomain.enable { jicofo = { authentication = { enabled = "true"; type = "XMPP"; login-url = cfg.hostName; }; xmpp.client.client-proxy = "focus.${cfg.hostName}"; }; })]; }; Loading @@ -430,7 +570,7 @@ in xmppDomain = cfg.hostName; control.muc = { domain = "internal.${cfg.hostName}"; domain = "internal.auth.${cfg.hostName}"; roomName = "JibriBrewery"; nickname = "jibri"; }; Loading
pkgs/servers/jitsi-excalidraw/default.nix 0 → 100644 +40 −0 Original line number Diff line number Diff line { lib , buildNpmPackage , fetchFromGitHub , nodejs , python3 }: buildNpmPackage rec { pname = "jitsi-excalidraw-backend"; version = "17"; src = fetchFromGitHub { owner = "jitsi"; repo = "excalidraw-backend"; rev = "x${version}"; hash = "sha256-aQePkVA8KRL06VewiD0ePRpj88pAItcV7B2SBnRRtCs="; }; npmDepsHash = "sha256-BJqjaqTeg5i+ECGMuiBYVToK2i2XCOVP9yeDFz6nP4k="; nativeBuildInputs = [ python3 ]; installPhase = '' mkdir -p $out/share cp -r {node_modules,dist} $out/share ''; postFixup = '' makeWrapper ${nodejs}/bin/node $out/bin/jitsi-excalidraw-backend \ --add-flags dist/index.js \ --chdir $out/share ''; meta = with lib; { description = "Excalidraw collaboration backend for Jitsi"; homepage = "https://github.com/jitsi/excalidraw-backend"; license = licenses.mit; maintainers = with maintainers; [ camillemndn ]; }; }
pkgs/top-level/all-packages.nix +2 −0 Original line number Diff line number Diff line Loading @@ -26552,6 +26552,8 @@ with pkgs; jicofo = callPackage ../servers/jicofo { }; jitsi-excalidraw = callPackage ../servers/jitsi-excalidraw { }; jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { }; jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { };