{ pkgs, config, service_configs, username, lib, inputs, ... }: { imports = [ (lib.serviceMountDeps "qbittorrent" [ service_configs.torrents_path config.services.qbittorrent.serverConfig.Preferences.Downloads.TempPath "${config.services.qbittorrent.profileDir}/qBittorrent" ]) (lib.vpnNamespaceOpenPort config.services.qbittorrent.webuiPort "qbittorrent") (lib.serviceDependZpool "qbittorrent" service_configs.zpool_hdds) ]; services.qbittorrent = { enable = true; webuiPort = service_configs.ports.torrent; profileDir = "/var/lib/qBittorrent"; serverConfig.LegalNotice.Accepted = true; serverConfig.Preferences = { WebUI = { AlternativeUIEnabled = true; RootFolder = "${pkgs.vuetorrent}/share/vuetorrent"; # disable auth because we use caddy for auth AuthSubnetWhitelist = "0.0.0.0/0"; AuthSubnetWhitelistEnabled = true; }; Downloads = { inherit (service_configs.torrent) SavePath TempPath; }; }; serverConfig.BitTorrent = { Session = { MaxConnectionsPerTorrent = 10; MaxUploadsPerTorrent = 10; MaxConnections = -1; MaxUploads = -1; MaxActiveCheckingTorrents = 5; # queueing QueueingSystemEnabled = false; MaxActiveDownloads = 2; # num of torrents that can download at the same time MaxActiveUploads = 20; IgnoreSlowTorrentsForQueueing = true; GlobalUPSpeedLimit = 0; GlobalDLSpeedLimit = 0; # Alternate speed limits for when Jellyfin is streaming AlternativeGlobalUPSpeedLimit = 500; # 500 KB/s when throttled AlternativeGlobalDLSpeedLimit = 800; # 800 KB/s when throttled IncludeOverheadInLimits = true; GlobalMaxRatio = 6.0; AddTrackersEnabled = true; AdditionalTrackers = lib.concatStringsSep "\\n" ( lib.lists.filter (x: x != "") ( lib.strings.splitString "\n" (builtins.readFile "${inputs.trackerlist}/trackers_all.txt") ) ); AnnounceToAllTrackers = true; # idk why it also has to be specified here too? inherit (config.services.qbittorrent.serverConfig.Preferences.Downloads) TempPath; TempPathEnabled = true; # how many connections per sec ConnectionSpeed = 300; ChokingAlgorithm = "RateBased"; PieceExtentAffinity = true; SuggestMode = true; }; Network = { # traffic is routed through a vpn, we don't need # port forwarding PortForwardingEnabled = false; }; }; }; systemd.services.qbittorrent.serviceConfig.TimeoutStopSec = lib.mkForce 10; systemd.tmpfiles.rules = [ "Z ${config.services.qbittorrent.serverConfig.Preferences.Downloads.SavePath} 0750 ${config.services.qbittorrent.user} ${service_configs.media_group}" "Z ${config.services.qbittorrent.serverConfig.Preferences.Downloads.TempPath} 0700 ${config.services.qbittorrent.user} ${config.services.qbittorrent.group}" "Z ${config.services.qbittorrent.profileDir} 0700 ${config.services.qbittorrent.user} ${config.services.qbittorrent.group}" ]; services.caddy.virtualHosts."torrent.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} reverse_proxy ${service_configs.https.wg_ip}:${builtins.toString config.services.qbittorrent.webuiPort} ''; users.users.${config.services.qbittorrent.user}.extraGroups = [ service_configs.media_group ]; }