{ config, lib, pkgs, ... }: let serviceConfig = import ../config/services.nix; cfg = serviceConfig.livekit; keyFile = cfg.keyFile; acmeDir = config.security.acme.certs.${cfg.domain}.directory; publicUrl = "wss://${cfg.domain}"; trustedHomeservers = if builtins.isList cfg.trusted_homeservers then cfg.trusted_homeservers else throw "config/services.nix livekit.trusted_homeservers must be a list of domains."; trustedHomeserversEnv = builtins.concatStringsSep "," trustedHomeservers; in { services.livekit = lib.mkIf cfg.enable { enable = true; settings.room.auto_create = false; inherit keyFile; openFirewall = true; settings = { port = cfg.port; rtc = { port_range_start = cfg.rtc_port_range_start; port_range_end = cfg.rtc_port_range_end; }; turn = { enabled = true; udp_port = cfg.turn_port; tls_port = cfg.turn_tls_port; relay_range_start = cfg.turn_relay_range_start; relay_range_end = cfg.turn_relay_range_end; domain = cfg.domain; cert_file = "/run/credentials/livekit.service/turn-cert"; key_file = "/run/credentials/livekit.service/turn-key"; }; }; }; # Provide ACME cert/key to livekit via systemd credentials. systemd.services.livekit.serviceConfig.LoadCredential = lib.mkIf cfg.enable (lib.mkAfter [ "turn-cert:${acmeDir}/full.pem" "turn-key:${acmeDir}/key.pem" ]); # Restart livekit when ACME renews the cert used for built-in TURN TLS. security.acme.certs.${cfg.domain}.postRun = lib.mkIf cfg.enable "systemctl restart livekit.service"; services.lk-jwt-service = lib.mkIf cfg.enable { enable = true; livekitUrl = publicUrl; inherit keyFile; port = cfg.jwt_port; }; systemd.services.livekit-key = lib.mkIf cfg.enable { before = [ "lk-jwt-service.service" "livekit.service" ]; wantedBy = [ "multi-user.target" ]; path = with pkgs; [ livekit coreutils gawk ]; script = '' echo "Key missing, generating key" mkdir -p "$(dirname "${keyFile}")" echo "lk-jwt-service: $(livekit-server generate-keys | tail -1 | awk '{print $3}')" > "${keyFile}" ''; serviceConfig.Type = "oneshot"; unitConfig.ConditionPathExists = "!${keyFile}"; }; systemd.services.lk-jwt-service = lib.mkIf cfg.enable { environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = trustedHomeserversEnv; }; # Open firewall for livekit RTC ports networking.firewall.allowedUDPPorts = lib.mkIf cfg.enable ( (lib.range cfg.rtc_port_range_start cfg.rtc_port_range_end) ++ (lib.range cfg.turn_relay_range_start cfg.turn_relay_range_end) ++ [ cfg.turn_port ] ); # Open firewall for livekit API/JWT and TURN TCP/TLS ports networking.firewall.allowedTCPPorts = lib.mkIf cfg.enable [ 7880 7881 cfg.turn_port cfg.turn_tls_port ]; }