From 3408ceb62c7673dea4531eeb8a77df10420a55e4 Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Mon, 2 Sep 2024 19:14:35 +0530 Subject: [PATCH] feat: add nix module for arr suite Can finally deploy: * Jellyfin * Jellyseerr * Radarr, Prowlarr, Sonarr, Bazarr * QBitTorrent + VueTorrent Signed-off-by: Chinmay D. Pai --- modules/nixos/services/arr/bazarr/default.nix | 18 +++++ modules/nixos/services/arr/default.nix | 57 +++++--------- .../nixos/services/arr/jellyfin/default.nix | 66 ++++++++++++++++ .../nixos/services/arr/jellyseerr/default.nix | 26 +++++++ .../nixos/services/arr/prowlarr/default.nix | 14 ++++ .../services/arr/qbittorrent/default.nix | 76 +++++++++++++++++++ modules/nixos/services/arr/radarr/default.nix | 15 ++++ modules/nixos/services/arr/sonarr/default.nix | 15 ++++ packages/vuetorrent/default.nix | 35 +++++++++ 9 files changed, 284 insertions(+), 38 deletions(-) create mode 100644 modules/nixos/services/arr/bazarr/default.nix create mode 100644 modules/nixos/services/arr/jellyfin/default.nix create mode 100644 modules/nixos/services/arr/jellyseerr/default.nix create mode 100644 modules/nixos/services/arr/prowlarr/default.nix create mode 100644 modules/nixos/services/arr/qbittorrent/default.nix create mode 100644 modules/nixos/services/arr/radarr/default.nix create mode 100644 modules/nixos/services/arr/sonarr/default.nix create mode 100644 packages/vuetorrent/default.nix diff --git a/modules/nixos/services/arr/bazarr/default.nix b/modules/nixos/services/arr/bazarr/default.nix new file mode 100644 index 0000000..620c8a1 --- /dev/null +++ b/modules/nixos/services/arr/bazarr/default.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: { + options.snowflake.services.bazarr = { + enable = lib.mkEnableOption "Enable bazarr deployment configuration"; + }; + + # NOTE: No good subtitle providers are available right now. + # There's no need to enable bazarr, private trackers have decent + # subtitles for releases. + config = lib.mkIf config.snowflake.services.bazarr.enable { + services.bazarr.enable = true; + services.bazarr.group = "media"; + services.bazarr.openFirewall = true; + }; +} diff --git a/modules/nixos/services/arr/default.nix b/modules/nixos/services/arr/default.nix index 0b6c0de..72636f1 100644 --- a/modules/nixos/services/arr/default.nix +++ b/modules/nixos/services/arr/default.nix @@ -1,51 +1,32 @@ { config, lib, - pkgs, ... }: { options.snowflake.services.arr = { enable = lib.mkEnableOption "Enable arr suite configuration"; - jellyfin.enable = lib.mkEnableOption "Enable jellyfin configuration for NixOS"; - # mediaDir = lib.mkOption { - # type = lib.types.path; - # description = "Path to media storage directory, accessible by all *arr suite applications"; - # }; + monitoring = { + enable = lib.mkEnableOption "Enable monitoring for arr suite"; + sonarrApiKeyFile = lib.mkOption { + description = "Age module containing the sonarr API Key to use for monitoring"; + }; + radarrApiKeyFile = lib.mkOption { + description = "Age module containing the radarr API Key to use for monitoring"; + }; + }; }; - config = let - cfg = config.snowflake.services.arr; - in - lib.mkIf cfg.enable { - services.jellyfin = { - enable = cfg.jellyfin.enable; + config = lib.mkIf config.snowflake.services.arr.enable { + snowflake.services = { + jellyfin.enable = true; + jellyseerr.enable = true; + radarr.enable = true; + sonarr.enable = true; + prowlarr.enable = true; + qbittorrent-nox = { + enable = true; openFirewall = true; }; - - users.groups.media = { - members = ["@wheel" "jellyfin"]; - }; - - nixpkgs.config.packageOverrides = pkgs: { - jellyfin-ffmpeg = pkgs.jellyfin-ffmpeg.override { - ffmpeg_6-full = pkgs.ffmpeg_6-full.override { - withMfx = false; - withVpl = true; - }; - }; - }; - - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ - intel-media-driver - intel-compute-runtime - onevpl-intel-gpu - libvdpau-va-gl - ]; - }; - - services.jellyseerr.enable = true; - services.jellyseerr.openFirewall = true; }; + }; } diff --git a/modules/nixos/services/arr/jellyfin/default.nix b/modules/nixos/services/arr/jellyfin/default.nix new file mode 100644 index 0000000..da5fc1d --- /dev/null +++ b/modules/nixos/services/arr/jellyfin/default.nix @@ -0,0 +1,66 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.services.jellyfin = { + enable = lib.mkEnableOption "Enable jellyfin deployment configuration"; + }; + + config = let + cfg = config.snowflake.services.jellyfin; + in + lib.mkIf cfg.enable { + services.jellyfin = { + enable = true; + openFirewall = true; + }; + + users.groups.media = { + members = ["@wheel" "jellyfin"]; + }; + + nixpkgs.config.packageOverrides = pkgs: { + jellyfin-ffmpeg = pkgs.jellyfin-ffmpeg.override { + ffmpeg_6-full = pkgs.ffmpeg_6-full.override { + withMfx = false; + withVpl = true; + }; + }; + vaapiIntel = pkgs.vaapiIntel.override {enableHybridCodec = true;}; + }; + + environment.systemPackages = with pkgs; [ + jellyfin-ffmpeg + ]; + + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver + intel-compute-runtime + vpl-gpu-rt + vaapiIntel + vaapiVdpau + libvdpau-va-gl + ]; + }; + + services.jellyseerr.enable = true; + services.jellyseerr.openFirewall = true; + + services.nginx = { + virtualHosts = { + "jelly.deku.moe" = { + serverName = "jelly.deku.moe"; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:8096/"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/arr/jellyseerr/default.nix b/modules/nixos/services/arr/jellyseerr/default.nix new file mode 100644 index 0000000..e299e8e --- /dev/null +++ b/modules/nixos/services/arr/jellyseerr/default.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + ... +}: { + options.snowflake.services.jellyseerr = { + enable = lib.mkEnableOption "Enable jellyseerr deployment configuration"; + }; + + config = lib.mkIf config.snowflake.services.jellyseerr.enable { + services.jellyseerr.enable = true; + services.jellyseerr.openFirewall = true; + services.nginx = { + virtualHosts = { + "seerr.deku.moe" = { + serverName = "seerr.deku.moe"; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:5055/"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/arr/prowlarr/default.nix b/modules/nixos/services/arr/prowlarr/default.nix new file mode 100644 index 0000000..d5bc951 --- /dev/null +++ b/modules/nixos/services/arr/prowlarr/default.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: { + options.snowflake.services.prowlarr = { + enable = lib.mkEnableOption "Enable prowlarr deployment configuration"; + }; + + config = lib.mkIf config.snowflake.services.prowlarr.enable { + services.prowlarr.enable = true; + services.prowlarr.openFirewall = true; + }; +} diff --git a/modules/nixos/services/arr/qbittorrent/default.nix b/modules/nixos/services/arr/qbittorrent/default.nix new file mode 100644 index 0000000..75b6f97 --- /dev/null +++ b/modules/nixos/services/arr/qbittorrent/default.nix @@ -0,0 +1,76 @@ +{ + config, + lib, + pkgs, + namespace, + ... +}: { + options.snowflake.services.qbittorrent-nox = { + enable = lib.mkEnableOption "Enable qbittorrent-nox service configuration"; + + package = lib.mkPackageOption pkgs "qbittorrent-nox" {}; + + openFirewall = lib.mkOption { + description = "Allow firewall access for qbittorrent-nox"; + type = lib.types.bool; + default = false; + }; + + uiPort = lib.mkOption { + description = "Web UI Port for qbittorrent-nox"; + type = lib.types.port; + default = 8069; + }; + + torrentPort = lib.mkOption { + description = "Torrenting port"; + type = with lib.types; nullOr port; + default = 64211; + }; + }; + + config = let + cfg = config.snowflake.services.qbittorrent-nox; + in + lib.mkIf cfg.enable { + networking.firewall.allowedTCPPorts = + lib.optional (cfg.openFirewall && cfg.torrentPort != null) cfg.torrentPort + ++ lib.optional cfg.openFirewall cfg.uiPort; + networking.firewall.allowedUDPPorts = + lib.optional (cfg.openFirewall && cfg.torrentPort != null) cfg.torrentPort; + + users.users.qbittorrent-nox = { + isSystemUser = true; + group = "media"; + home = "/var/lib/qbittorrent-nox"; + }; + + systemd.services.qbittorrent-nox = { + description = "qBittorrent-nox service"; + wants = ["network-online.target"]; + after = ["local-fs.target" "network-online.target" "nss-lookup.target"]; + wantedBy = ["multi-user.target"]; + unitConfig.Documentation = "man:qbittorrent-nox(1)"; + # required for reverse proxying + preStart = '' + rm -rf /var/lib/qbittorrent-nox/qBittorrent/config/vuetorrent + ln -sf ${pkgs.${namespace}.vuetorrent} /var/lib/qbittorrent-nox/qBittorrent/config/vuetorrent + + if [[ ! -f /var/lib/qbittorrent-nox/qBittorrent/config/qBittorrent.conf ]]; then + mkdir -p /var/lib/qbittorrent-nox/qBittorrent/config + echo "Preferences\WebUI\HostHeaderValidation=false" >> /var/lib/qbittorrent-nox/qBittorrent/config/qBittorrent.conf + fi + ''; + serviceConfig = { + User = "qbittorrent-nox"; + Group = "media"; + StateDirectory = "qbittorrent-nox"; + WorkingDirectory = "/var/lib/qbittorrent-nox"; + ExecStart = '' + ${cfg.package}/bin/qbittorrent-nox ${lib.optionalString (cfg.torrentPort != null) "--torrenting-port=${toString cfg.torrentPort}"} \ + --webui-port=${toString cfg.uiPort} --profile=/var/lib/qbittorrent-nox + ''; + }; + }; + }; +} diff --git a/modules/nixos/services/arr/radarr/default.nix b/modules/nixos/services/arr/radarr/default.nix new file mode 100644 index 0000000..242a165 --- /dev/null +++ b/modules/nixos/services/arr/radarr/default.nix @@ -0,0 +1,15 @@ +{ + config, + lib, + ... +}: { + options.snowflake.services.radarr = { + enable = lib.mkEnableOption "Enable radarr deployment configuration"; + }; + + config = lib.mkIf config.snowflake.services.radarr.enable { + services.radarr.enable = true; + services.radarr.group = "media"; + services.radarr.openFirewall = true; + }; +} diff --git a/modules/nixos/services/arr/sonarr/default.nix b/modules/nixos/services/arr/sonarr/default.nix new file mode 100644 index 0000000..b13eecf --- /dev/null +++ b/modules/nixos/services/arr/sonarr/default.nix @@ -0,0 +1,15 @@ +{ + config, + lib, + ... +}: { + options.snowflake.services.sonarr = { + enable = lib.mkEnableOption "Enable sonarr deployment configuration"; + }; + + config = lib.mkIf config.snowflake.services.sonarr.enable { + services.sonarr.enable = true; + services.sonarr.group = "media"; + services.sonarr.openFirewall = true; + }; +} diff --git a/packages/vuetorrent/default.nix b/packages/vuetorrent/default.nix new file mode 100644 index 0000000..6bfae5a --- /dev/null +++ b/packages/vuetorrent/default.nix @@ -0,0 +1,35 @@ +{ + pkgs, + lib, + stdenv, + ... +}: +stdenv.mkDerivation rec { + pname = "vuetorrent"; + version = "2.10.2"; + + src = pkgs.fetchurl { + url = "https://github.com/WDaan/VueTorrent/releases/download/v${version}/vuetorrent.zip"; + sha256 = "sha256-pJzj3jHXmpKca1zyOTlzUQvp7/LtjjMGNt9SMDo89yo="; + }; + + buildInputs = with pkgs; [unzip]; + + unpackPhase = '' + unzip $src + ''; + + dontStrip = true; + + installPhase = '' + mkdir -p $out/ + cp -r vuetorrent/public/ $out/ + ''; + + meta = with lib; { + description = "The sleekest looking WEBUI for qBittorrent made with Vuejs! "; + homepage = "https://github.com/WDaan/VueTorrent"; + license = [licenses.gpl3Only]; + platforms = ["x86_64-darwin" "aarch64-darwin" "aarch64-linux" "x86_64-linux"]; + }; +}