From 79a37fa8eb29c1097d656b5b5f99f2c162d47af4 Mon Sep 17 00:00:00 2001 From: ooks-io Date: Mon, 2 Dec 2024 12:30:30 +1100 Subject: [PATCH] ookflix: add containers --- .../nixos/server/services/ookflix/default.nix | 10 +++ .../server/services/ookflix/jellyfin.nix | 8 +-- .../server/services/ookflix/jellyseer.nix | 32 ++++----- modules/nixos/server/services/ookflix/lib.nix | 19 +++++- .../nixos/server/services/ookflix/options.nix | 20 ++++-- .../nixos/server/services/ookflix/plex.nix | 3 +- .../server/services/ookflix/prowlarr.nix | 42 ++++++++++++ .../nixos/server/services/ookflix/radarr.nix | 41 ++++++++++++ .../nixos/server/services/ookflix/shared.nix | 66 +++++++++++++++++++ .../nixos/server/services/ookflix/sonarr.nix | 44 +++++++++++++ .../server/services/ookflix/tautulli.nix | 5 +- .../server/services/ookflix/transmission.nix | 43 ++++++++++++ .../nixos/server/services/ookflix/users.nix | 38 ----------- 13 files changed, 303 insertions(+), 68 deletions(-) create mode 100644 modules/nixos/server/services/ookflix/prowlarr.nix create mode 100644 modules/nixos/server/services/ookflix/radarr.nix create mode 100644 modules/nixos/server/services/ookflix/shared.nix create mode 100644 modules/nixos/server/services/ookflix/sonarr.nix create mode 100644 modules/nixos/server/services/ookflix/transmission.nix delete mode 100644 modules/nixos/server/services/ookflix/users.nix diff --git a/modules/nixos/server/services/ookflix/default.nix b/modules/nixos/server/services/ookflix/default.nix index 8b99d22..f14c124 100644 --- a/modules/nixos/server/services/ookflix/default.nix +++ b/modules/nixos/server/services/ookflix/default.nix @@ -9,6 +9,14 @@ in { imports = [ ./jellyfin.nix ./plex.nix + ./jellyseer.nix + ./tautulli.nix + ./sonarr.nix + ./prowlarr.nix + ./gluetun.nix + ./transmission.nix + ./shared.nix + ./options.nix ]; @@ -18,6 +26,8 @@ in { services = { jellyfin.enable = true; plex.enable = true; + jellyseer.enable = true; + tautulli.enable = true; }; }; }; diff --git a/modules/nixos/server/services/ookflix/jellyfin.nix b/modules/nixos/server/services/ookflix/jellyfin.nix index cf6738f..0692b0e 100644 --- a/modules/nixos/server/services/ookflix/jellyfin.nix +++ b/modules/nixos/server/services/ookflix/jellyfin.nix @@ -2,9 +2,10 @@ config, lib, ook, + self, ... }: let - ookflixLib = import ./lib.nix {inherit lib config;}; + ookflixLib = import ./lib.nix {inherit lib config self;}; inherit (ookflixLib) mkServiceStateDir mkServiceUser; inherit (lib) mkIf optionalAttrs; inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; @@ -22,10 +23,9 @@ in { image = "lscr.io/linuxserver/jellyfin:latest"; autoStart = true; hostname = "jellyfin"; - ports = [(mkContainerPort jellyfin.port)]; + ports = ["${jellyfin.port}:${jellyfin.port}"]; volumes = [ - "${volumes.media.movies}:/data/movies" - "${volumes.media.tv}:/data/tv" + "${volumes.media.root}:/data" "${jellyfin.stateDir}:/config" ]; labels = mkContainerLabel { diff --git a/modules/nixos/server/services/ookflix/jellyseer.nix b/modules/nixos/server/services/ookflix/jellyseer.nix index 382c63d..c0cf5f3 100644 --- a/modules/nixos/server/services/ookflix/jellyseer.nix +++ b/modules/nixos/server/services/ookflix/jellyseer.nix @@ -6,27 +6,29 @@ }: let inherit (lib) mkIf; inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; - inherit (config.ooknet.server.ookflix) storage groups; + inherit (config.ooknet.server.ookflix) groups; inherit (config.ooknet.server.ookflix.services) jellyseer; in { config = mkIf jellyseer.enable { # media requesting for jellyfin - jellyseer = { - image = "fallenbagel/jellyseerr:latest"; - autoStart = true; - hostname = "jellyseer"; - ports = [(mkContainerPort jellyseer.port)]; - volumes = ["${storage.state.jellyseer}:/config"]; - extraOptions = ["--network" "host"]; - labels = mkContainerLabel { - name = "jellyseer"; - inherit (jellyseer) domain port; - homepage = { - group = "media"; - description = "media-server requesting"; + virtualisation.oci-containers.containers = { + jellyseer = { + image = "fallenbagel/jellyseerr:latest"; + autoStart = true; + hostname = "jellyseer"; + ports = [(mkContainerPort jellyseer.port)]; + volumes = ["${jellyseer.stateDir}:/config"]; + extraOptions = ["--network" "host"]; + labels = mkContainerLabel { + name = "jellyseer"; + inherit (jellyseer) domain port; + homepage = { + group = "media"; + description = "media-server requesting"; + }; }; + environment = mkContainerEnvironment jellyseer.user.id groups.media.id; }; - environment = mkContainerEnvironment jellyseer.user.id groups.media.id; }; }; } diff --git a/modules/nixos/server/services/ookflix/lib.nix b/modules/nixos/server/services/ookflix/lib.nix index ba25024..6cc065d 100644 --- a/modules/nixos/server/services/ookflix/lib.nix +++ b/modules/nixos/server/services/ookflix/lib.nix @@ -1,6 +1,7 @@ { lib, config, + self, ... }: let inherit (lib) mkOption mkEnableOption elem assertMsg; @@ -87,6 +88,15 @@ user = mkUserOption name args.uid; group = mkGroupOption name args.gid; }; + mkBasicServiceOptions = name: { + gid, + uid, + ... + } @ args: { + enable = mkEnableOption "Enable ${name} container"; + user = mkUserOption name args.uid; + group = mkGroupOption name args.gid; + }; mkServiceUser = service: { users.${service} = { isSystemUser = true; @@ -106,6 +116,13 @@ group = cfg.services.${service}.group.name; }; }; + mkServiceSecret = name: service: { + ${name} = { + file = "${self}/secrets/container/${name}.age"; + owner = cfg.services.${service}.user.name; + group = cfg.services.${service}.group.name; + }; + }; in { - inherit mkServiceOptions mkServiceStateDir mkServiceUser mkUserOption mkPortOption mkGroupOption mkVolumeOption mkSubdomainOption; + inherit mkServiceSecret mkBasicServiceOptions mkServiceOptions mkServiceStateDir mkServiceUser mkUserOption mkPortOption mkGroupOption mkVolumeOption mkSubdomainOption; } diff --git a/modules/nixos/server/services/ookflix/options.nix b/modules/nixos/server/services/ookflix/options.nix index 7cd5550..8d0637b 100644 --- a/modules/nixos/server/services/ookflix/options.nix +++ b/modules/nixos/server/services/ookflix/options.nix @@ -1,11 +1,12 @@ { lib, config, + self, ... }: let - ookflixLib = import ./lib.nix {inherit lib config;}; + ookflixLib = import ./lib.nix {inherit lib config self;}; - inherit (ookflixLib) mkVolumeOption mkGroupOption mkServiceOptions; + inherit (ookflixLib) mkVolumeOption mkGroupOption mkServiceOptions mkBasicServiceOptions; inherit (lib) mkOption mkEnableOption; inherit (lib.types) enum; inherit (config.ooknet) server; @@ -26,24 +27,25 @@ in { }; volumes = { state.root = mkVolumeOption "root" "/var/lib/ookflix"; - content.root = mkVolumeOption "root" "/jellyfin"; + data.root = mkVolumeOption "root" "/jellyfin"; downloads = { root = mkVolumeOption "${cfg.content.root}/downloads"; - incomplete = mkVolumeOption "downloads" "incomplete"; - complete = mkVolumeOption "downloads" "complete"; - watch = mkVolumeOption "downloads" "watch"; + tv = mkVolumeOption "downloads" "tv"; + movies = mkVolumeOption "downloads" "movies"; + books = mkVolumeOption "downloads" "books"; }; media = { root = mkVolumeOption "root" "${cfg.volumes.content.root}/media"; movies = mkVolumeOption "media" "movies"; tv = mkVolumeOption "media" "tv"; + books = mkVolumeOption "media" "books"; }; }; # Shared groups groups = { media = mkGroupOption "media" 992; - downloader = mkGroupOption "downloader" 981; + downloads = mkGroupOption "downloader" 981; }; services = { @@ -87,6 +89,10 @@ in { uid = 355; gid = 355; }; + gluetun = mkBasicServiceOptions "gluetun" { + uid = 356; + gid = 357; + }; }; }; } diff --git a/modules/nixos/server/services/ookflix/plex.nix b/modules/nixos/server/services/ookflix/plex.nix index 1bee37e..7353e97 100644 --- a/modules/nixos/server/services/ookflix/plex.nix +++ b/modules/nixos/server/services/ookflix/plex.nix @@ -2,9 +2,10 @@ config, lib, ook, + self, ... }: let - ookflixLib = import ./lib.nix {inherit lib config;}; + ookflixLib = import ./lib.nix {inherit lib config self;}; inherit (ookflixLib) mkServiceUser mkServiceStateDir; inherit (lib) mkIf optionalAttrs; inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; diff --git a/modules/nixos/server/services/ookflix/prowlarr.nix b/modules/nixos/server/services/ookflix/prowlarr.nix new file mode 100644 index 0000000..ca8e5ed --- /dev/null +++ b/modules/nixos/server/services/ookflix/prowlarr.nix @@ -0,0 +1,42 @@ +{ + config, + lib, + ook, + self, + ... +}: let + ookflixLib = import ./lib.nix {inherit lib config self;}; + inherit (ookflixLib) mkServiceUser mkServiceStateDir; + inherit (lib) mkIf; + inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; + inherit (config.ooknet.server.ookflix) groups; + inherit (config.ooknet.server.ookflix.services) prowlarr; +in { + config = mkIf prowlarr.enable { + users = mkServiceUser prowlarr.user.name; + systemd.tmpfiles = mkServiceStateDir "prowlarr" prowlarr.stateDir; + virtualisation.oci-containers.containers = { + prowlarr = { + image = "lscr.io/linuxserver/prowlarr:latest"; + autoStart = true; + hostname = "prowlarr"; + ports = [(mkContainerPort prowlarr.port)]; + volumes = ["${prowlarr.stateDir}:/config"]; + extraOptions = ["--network" "host"]; + labels = mkContainerLabel { + name = "prowlarr"; + inherit (prowlarr) port domain; + homepage = { + group = "arr"; + description = "media-server indexer"; + }; + }; + environment = + mkContainerEnvironment prowlarr.user.id groups.media.id + // { + UMASK = "002"; + }; + }; + }; + }; +} diff --git a/modules/nixos/server/services/ookflix/radarr.nix b/modules/nixos/server/services/ookflix/radarr.nix new file mode 100644 index 0000000..d478631 --- /dev/null +++ b/modules/nixos/server/services/ookflix/radarr.nix @@ -0,0 +1,41 @@ +{ + config, + lib, + ook, + self, + ... +}: let + ookflixLib = import ./lib.nix {inherit lib config self;}; + inherit (ookflixLib) mkServiceUser mkServiceStateDir; + inherit (lib) mkIf; + inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment; + inherit (config.ooknet.server.ookflix) groups volumes; + inherit (config.ooknet.server.ookflix.services) radarr; +in { + config = mkIf radarr.enable { + users = mkServiceUser radarr.user.name; + systemd.tmpfiles = mkServiceStateDir "radarr" radarr.stateDir; + virtualisation.oci-containers.containers = { + radarr = { + image = "ghcr.io/hotio/qbittorrent"; + autoStart = true; + hostname = "radarr"; + ports = ["${radarr.port}:${radarr.port}"]; + volumes = [ + "${radarr.stateDir}:/config" + "${volumes.data.root}:/data" + ]; + extraOptions = ["--network" "host"]; + labels = mkContainerLabel { + name = "radarr"; + inherit (radarr) port domain; + homepage = { + group = "arr"; + description = "media-server movies downloader"; + }; + }; + environment = mkContainerEnvironment radarr.user.id groups.media.id; + }; + }; + }; +} diff --git a/modules/nixos/server/services/ookflix/shared.nix b/modules/nixos/server/services/ookflix/shared.nix new file mode 100644 index 0000000..87a5117 --- /dev/null +++ b/modules/nixos/server/services/ookflix/shared.nix @@ -0,0 +1,66 @@ +{ + lib, + config, + ... +}: let + inherit (lib) mkIf; + inherit (config.ooknet.host) admin; + inherit (config.ooknet.server) ookflix; + inherit (config.ooknet.server.ookflix) volumes groups; + inherit (config.ooknet.server.ookflix.services) jellyfin plex sonarr radarr prowlarr transmission; + mediaDirPermissions = { + mode = "0775"; + user = admin.name; + group = groups.media.name; + }; + downloadDirPermissions = { + mode = "0770"; + user = admin.name; + group = groups.downloads.name; + }; + ifTheyExist = users: builtins.filter (user: builtins.hasAttr user config.users.users) users; +in { + config = mkIf ookflix.enable { + users.groups = { + ${groups.media.name} = { + inherit (groups.media) name gid; + members = ifTheyExist [ + jellyfin.user.name + plex.user.name + sonarr.user.name + radarr.user.name + prowlarr.user.name + ]; + }; + ${groups.downloads.name} = { + inherit (groups.downloads) name gid; + members = ifTheyExist [ + sonarr.user.name + radarr.user.name + prowlarr.user.name + transmission.user.name + ]; + }; + }; + systemd.tmpfiles.settings = { + contentRoot = { + "${volumes.content.root}"."d" = { + mode = "0775"; + user = "root"; + group = "root"; + }; + }; + mediaDirectories = { + "${volumes.media.root}"."d" = mediaDirPermissions; + "${volumes.media.tv}"."d" = mediaDirPermissions; + "${volumes.media.movies}"."d" = mediaDirPermissions; + }; + downloadDirectories = { + "${volumes.downloads.root}"."d" = downloadDirPermissions; + "${volumes.downloads.complete}"."d" = downloadDirPermissions; + "${volumes.downloads.incomplete}"."d" = downloadDirPermissions; + "${volumes.downloads.watch}"."d" = downloadDirPermissions; + }; + }; + }; +} diff --git a/modules/nixos/server/services/ookflix/sonarr.nix b/modules/nixos/server/services/ookflix/sonarr.nix new file mode 100644 index 0000000..c6384c8 --- /dev/null +++ b/modules/nixos/server/services/ookflix/sonarr.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + ook, + self, + ... +}: let + ookflixLib = import ./lib.nix {inherit lib config self;}; + inherit (ookflixLib) mkServiceUser mkServiceStateDir; + inherit (lib) mkIf; + inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; + inherit (config.ooknet.server.ookflix) groups volumes; + inherit (config.ooknet.server.ookflix.services) sonarr; +in { + config = mkIf sonarr.enable { + users = mkServiceUser sonarr.user.name; + systemd.tmpfiles = mkServiceStateDir "sonarr" sonarr.stateDir; + virtualisation.oci-containers.containers = { + sonarr = { + image = "ghcr.io/hotio/sonarr"; + autoStart = true; + hostname = "sonarr"; + ports = [(mkContainerPort sonarr.port)]; + volumes = [ + "${sonarr.stateDir}:/config" + "${volumes.data.root}:/data" + ]; + labels = mkContainerLabel { + name = "sonarr"; + inherit (sonarr) port domain; + homepage = { + group = "arr"; + description = "media-server tv downloader"; + }; + }; + environment = + mkContainerEnvironment sonarr.user.id groups.media.id + // { + UMASK = "002"; + }; + }; + }; + }; +} diff --git a/modules/nixos/server/services/ookflix/tautulli.nix b/modules/nixos/server/services/ookflix/tautulli.nix index f99fad6..5d1ec5d 100644 --- a/modules/nixos/server/services/ookflix/tautulli.nix +++ b/modules/nixos/server/services/ookflix/tautulli.nix @@ -2,14 +2,15 @@ config, lib, ook, + self, ... }: let - ookflixLib = import ./lib.nix {inherit lib config;}; + ookflixLib = import ./lib.nix {inherit lib config self;}; inherit (ookflixLib) mkServiceUser mkServiceStateDir; inherit (lib) mkIf; inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; inherit (config.ooknet.server.ookflix) groups; - inherit (config.ooknet.server.services) tautulli; + inherit (config.ooknet.server.ookflix.services) tautulli; in { config = mkIf tautulli.enable { users = mkServiceUser tautulli.user.name; diff --git a/modules/nixos/server/services/ookflix/transmission.nix b/modules/nixos/server/services/ookflix/transmission.nix new file mode 100644 index 0000000..0122cb3 --- /dev/null +++ b/modules/nixos/server/services/ookflix/transmission.nix @@ -0,0 +1,43 @@ +{ + config, + lib, + ook, + self, + ... +}: let + ookflixLib = import ./lib.nix {inherit lib config self;}; + inherit (ookflixLib) mkServiceUser mkServiceStateDir; + inherit (lib) mkIf; + inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort; + inherit (config.ooknet.server.ookflix) groups volumes; + inherit (config.ooknet.server.ookflix.services) transmission gluetun; +in { + config = mkIf transmission.enable { + users = mkServiceUser transmission.user.name; + systemd.tmpfiles = mkServiceStateDir "transmission" transmission.stateDir; + virtualisation.oci-containers.containers = { + # Torrent client + transmission = { + image = "lscr.io/linuxserver/transmission:latest"; + environmentFiles = [config.age.secrets.transmission_env.path]; + environment = mkContainerEnvironment transmission.user.id groups.downloads.id; + dependsOn = ["gluetun"]; + networkMode = "service:gluetun"; # Use VPN container's network + volumes = [ + "${transmission.stateDir}:/config" + "${volumes.downloads.root}:/downloads" + "${volumes.downloads.watch}:/watch" + ]; + extraOptions = ["--network=container:gluetun"]; + labels = mkContainerLabel { + name = "transmission"; + inherit (transmission) port domain; + homepage = { + group = "downloads"; + description = "torrent client"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/server/services/ookflix/users.nix b/modules/nixos/server/services/ookflix/users.nix deleted file mode 100644 index 63790b0..0000000 --- a/modules/nixos/server/services/ookflix/users.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - lib, - config, - ... -}: let - inherit (lib) mkIf mkMerge; - inherit (builtins) mapAttrs; - inherit (config.ooknet.server) ookflix; - inherit (config.ooknet.server.ookflix) services storage users groups; - - mkServiceUser = name: user: { - isSystemUser = true; - group = groups.${name}.name; - uid = users.${name}.id; - home = storage.state.${name}; - }; - - generateUsers = mapAttrs mkServiceUser users; -in { - config = mkIf ookflix.enable { - users = { - users = mkMerge [ - # media service users - (mkIf services.jellyfin.enable { - ${users.jellyfin.name} = mkServiceUser users.jellyfin.name groups.media.name; - }) - (mkIf services.plex.enable { - ${users.plex.name} = mkServiceUser users.plex.name groups.media.name; - }) - (mkIf (services.jellyfin.enable || services.jellyseer.enable) { - ${users.jellyseer.name} = mkServiceUser users.jellyseer.name groups.media.name; - }) - ]; - groups = { - }; - }; - }; -}