OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
HASH      79a37fa8eb29
DATE      2024-12-02
SUBJECT   ookflix: add containers
FILES     13 CHANGED
HASH      79a37fa8eb29
DATE      2024-12-02
SUBJECT   ookflix: add containers
FILES     13 CHANGED
 

diff --git a/modules/nixos/server/services/ookflix/default.nix b/modules/nixos/ser
ver/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/o
okflix/default.nix b/modules/nixos/server/se
rvices/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/se
rver/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 mkContainer
Port;
@@ -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/o
okflix/jellyfin.nix b/modules/nixos/server/s
ervices/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 li
b config;};
+  ookflixLib = import ./lib.nix {inherit li
b config self;};
   inherit (ookflixLib) mkServiceStateDir mk
ServiceUser;
   inherit (lib) mkIf optionalAttrs;
   inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
@@ -22,10 +23,9 @@ in {
         image = "lscr.io/linuxserver/jellyf
in:latest";
         autoStart = true;
         hostname = "jellyfin";
-        ports = [(mkContainerPort jellyfin.
port)];
+        ports = ["${jellyfin.port}:${jellyf
in.port}"];
         volumes = [
-          "${volumes.media.movies}:/data/mo
vies"
-          "${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/s
erver/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 mkContainer
Port;
-  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/o
okflix/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) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
-  inherit (config.ooknet.server.ookflix) st
orage groups;
+  inherit (config.ooknet.server.ookflix) gr
oups;
   inherit (config.ooknet.server.ookflix.ser
vices) jellyseer;
 in {
   config = mkIf jellyseer.enable {
     # media requesting for jellyfin
-    jellyseer = {
-      image = "fallenbagel/jellyseerr:lates
t";
-      autoStart = true;
-      hostname = "jellyseer";
-      ports = [(mkContainerPort jellyseer.p
ort)];
-      volumes = ["${storage.state.jellyseer
}:/config"];
-      extraOptions = ["--network" "host"];
-      labels = mkContainerLabel {
-        name = "jellyseer";
-        inherit (jellyseer) domain port;
-        homepage = {
-          group = "media";
-          description = "media-server reque
sting";
+    virtualisation.oci-containers.container
s = {
+      jellyseer = {
+        image = "fallenbagel/jellyseerr:lat
est";
+        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 req
uesting";
+          };
         };
+        environment = mkContainerEnvironmen
t 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 mkPortOpt
ion mkGroupOption mkVolumeOption mkSubdomainOption;
+  inherit mkServiceSecret mkBasicServiceOptions mkServiceOptions mkServiceStateDi
r mkServiceUser mkUserOption mkPortOption mkGroupOption mkVolumeOption mkSubdomain
Option;
 }

diff --git a/modules/nixos/server/services/o
okflix/lib.nix b/modules/nixos/server/servic
es/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 ele
m 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/${n
ame}.age";
+      owner = cfg.services.${service}.user.
name;
+      group = cfg.services.${service}.group
.name;
+    };
+  };
 in {
-  inherit mkServiceOptions mkServiceStateDi
r mkServiceUser mkUserOption mkPortOption mk
GroupOption mkVolumeOption mkSubdomainOption
;
+  inherit mkServiceSecret mkBasicServiceOpt
ions mkServiceOptions mkServiceStateDir mkSe
rviceUser mkUserOption mkPortOption mkGroupO
ption mkVolumeOption mkSubdomainOption;
 }
 

diff --git a/modules/nixos/server/services/ookflix/options.nix b/modules/nixos/ser
ver/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 mkBasicServi
ceOptions;
   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/o
okflix/options.nix b/modules/nixos/server/se
rvices/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 li
b config;};
+  ookflixLib = import ./lib.nix {inherit li
b config self;};
 
-  inherit (ookflixLib) mkVolumeOption mkGro
upOption mkServiceOptions;
+  inherit (ookflixLib) mkVolumeOption mkGro
upOption mkServiceOptions mkBasicServiceOpti
ons;
   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" "/j
ellyfin";
       downloads = {
         root = mkVolumeOption "${cfg.conten
t.root}/downloads";
-        incomplete = mkVolumeOption "downlo
ads" "incomplete";
-        complete = mkVolumeOption "download
s" "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" "mo
vies";
         tv = mkVolumeOption "media" "tv";
+        books = mkVolumeOption "media" "boo
ks";
       };
     };
     # Shared groups
     groups = {
       media = mkGroupOption "media" 992;
-      downloader = mkGroupOption "downloade
r" 981;
+      downloads = mkGroupOption "downloader
" 981;
     };
 
     services = {
@@ -87,6 +89,10 @@ in {
         uid = 355;
         gid = 355;
       };
+      gluetun = mkBasicServiceOptions "glue
tun" {
+        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 mkContainer
Port;

diff --git a/modules/nixos/server/services/o
okflix/plex.nix b/modules/nixos/server/servi
ces/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 li
b config;};
+  ookflixLib = import ./lib.nix {inherit li
b config self;};
   inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
   inherit (lib) mkIf optionalAttrs;
   inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
 

diff --git a/modules/nixos/server/services/ookflix/prowlarr.nix b/modules/nixos/se
rver/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 mkContainer
Port;
+  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/o
okflix/prowlarr.nix b/modules/nixos/server/s
ervices/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 li
b config self;};
+  inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
+  inherit (lib) mkIf;
+  inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
+  inherit (config.ooknet.server.ookflix) gr
oups;
+  inherit (config.ooknet.server.ookflix.ser
vices) prowlarr;
+in {
+  config = mkIf prowlarr.enable {
+    users = mkServiceUser prowlarr.user.nam
e;
+    systemd.tmpfiles = mkServiceStateDir "p
rowlarr" prowlarr.stateDir;
+    virtualisation.oci-containers.container
s = {
+      prowlarr = {
+        image = "lscr.io/linuxserver/prowla
rr:latest";
+        autoStart = true;
+        hostname = "prowlarr";
+        ports = [(mkContainerPort prowlarr.
port)];
+        volumes = ["${prowlarr.stateDir}:/c
onfig"];
+        extraOptions = ["--network" "host"]
;
+        labels = mkContainerLabel {
+          name = "prowlarr";
+          inherit (prowlarr) port domain;
+          homepage = {
+            group = "arr";
+            description = "media-server ind
exer";
+          };
+        };
+        environment =
+          mkContainerEnvironment prowlarr.u
ser.id groups.media.id
+          // {
+            UMASK = "002";
+          };
+      };
+    };
+  };
+}
 

diff --git a/modules/nixos/server/services/ookflix/radarr.nix b/modules/nixos/serv
er/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/o
okflix/radarr.nix b/modules/nixos/server/ser
vices/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 li
b config self;};
+  inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
+  inherit (lib) mkIf;
+  inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment;
+  inherit (config.ooknet.server.ookflix) gr
oups volumes;
+  inherit (config.ooknet.server.ookflix.ser
vices) radarr;
+in {
+  config = mkIf radarr.enable {
+    users = mkServiceUser radarr.user.name;
+    systemd.tmpfiles = mkServiceStateDir "r
adarr" radarr.stateDir;
+    virtualisation.oci-containers.container
s = {
+      radarr = {
+        image = "ghcr.io/hotio/qbittorrent"
;
+        autoStart = true;
+        hostname = "radarr";
+        ports = ["${radarr.port}:${radarr.p
ort}"];
+        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 mov
ies downloader";
+          };
+        };
+        environment = mkContainerEnvironmen
t radarr.user.id groups.media.id;
+      };
+    };
+  };
+}
 

diff --git a/modules/nixos/server/services/ookflix/shared.nix b/modules/nixos/serv
er/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 pro
wlarr 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/o
okflix/shared.nix b/modules/nixos/server/ser
vices/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) vo
lumes groups;
+  inherit (config.ooknet.server.ookflix.ser
vices) 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 (use
r: 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" = media
DirPermissions;
+        "${volumes.media.tv}"."d" = mediaDi
rPermissions;
+        "${volumes.media.movies}"."d" = med
iaDirPermissions;
+      };
+      downloadDirectories = {
+        "${volumes.downloads.root}"."d" = d
ownloadDirPermissions;
+        "${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/serv
er/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 mkContainer
Port;
+  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/o
okflix/sonarr.nix b/modules/nixos/server/ser
vices/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 li
b config self;};
+  inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
+  inherit (lib) mkIf;
+  inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
+  inherit (config.ooknet.server.ookflix) gr
oups volumes;
+  inherit (config.ooknet.server.ookflix.ser
vices) sonarr;
+in {
+  config = mkIf sonarr.enable {
+    users = mkServiceUser sonarr.user.name;
+    systemd.tmpfiles = mkServiceStateDir "s
onarr" sonarr.stateDir;
+    virtualisation.oci-containers.container
s = {
+      sonarr = {
+        image = "ghcr.io/hotio/sonarr";
+        autoStart = true;
+        hostname = "sonarr";
+        ports = [(mkContainerPort sonarr.po
rt)];
+        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.use
r.id groups.media.id
+          // {
+            UMASK = "002";
+          };
+      };
+    };
+  };
+}
 

diff --git a/modules/nixos/server/services/ookflix/tautulli.nix b/modules/nixos/se
rver/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 mkContainer
Port;
   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/o
okflix/tautulli.nix b/modules/nixos/server/s
ervices/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 li
b config;};
+  ookflixLib = import ./lib.nix {inherit li
b config self;};
   inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
   inherit (lib) mkIf;
   inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
   inherit (config.ooknet.server.ookflix) gr
oups;
-  inherit (config.ooknet.server.services) t
autulli;
+  inherit (config.ooknet.server.ookflix.ser
vices) tautulli;
 in {
   config = mkIf tautulli.enable {
     users = mkServiceUser tautulli.user.nam
e;
 

diff --git a/modules/nixos/server/services/ookflix/transmission.nix b/modules/nixo
s/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 mkContainer
Port;
+  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.download
s.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/o
okflix/transmission.nix b/modules/nixos/serv
er/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 li
b config self;};
+  inherit (ookflixLib) mkServiceUser mkServ
iceStateDir;
+  inherit (lib) mkIf;
+  inherit (ook.lib.container) mkContainerLa
bel mkContainerEnvironment mkContainerPort;
+  inherit (config.ooknet.server.ookflix) gr
oups volumes;
+  inherit (config.ooknet.server.ookflix.ser
vices) transmission gluetun;
+in {
+  config = mkIf transmission.enable {
+    users = mkServiceUser transmission.user
.name;
+    systemd.tmpfiles = mkServiceStateDir "t
ransmission" transmission.stateDir;
+    virtualisation.oci-containers.container
s = {
+      # Torrent client
+      transmission = {
+        image = "lscr.io/linuxserver/transm
ission:latest";
+        environmentFiles = [config.age.secr
ets.transmission_env.path];
+        environment = mkContainerEnvironmen
t transmission.user.id groups.downloads.id;
+        dependsOn = ["gluetun"];
+        networkMode = "service:gluetun"; # 
Use VPN container's network
+        volumes = [
+          "${transmission.stateDir}:/config
"
+          "${volumes.downloads.root}:/downl
oads"
+          "${volumes.downloads.watch}:/watc
h"
+        ];
+        extraOptions = ["--network=containe
r:gluetun"];
+        labels = mkContainerLabel {
+          name = "transmission";
+          inherit (transmission) port domai
n;
+          homepage = {
+            group = "downloads";
+            description = "torrent client";
+          };
+        };
+      };
+    };
+  };
+}
 

diff --git a/modules/nixos/server/services/ookflix/users.nix b/modules/nixos/serve
r/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.med
ia.name;
-        })
-      ];
-      groups = {
-      };
-    };
-  };
-}

diff --git a/modules/nixos/server/services/o
okflix/users.nix b/modules/nixos/server/serv
ices/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) se
rvices storage users groups;
-
-  mkServiceUser = name: user: {
-    isSystemUser = true;
-    group = groups.${name}.name;
-    uid = users.${name}.id;
-    home = storage.state.${name};
-  };
-
-  generateUsers = mapAttrs mkServiceUser us
ers;
-in {
-  config = mkIf ookflix.enable {
-    users = {
-      users = mkMerge [
-        # media service users
-        (mkIf services.jellyfin.enable {
-          ${users.jellyfin.name} = mkServic
eUser users.jellyfin.name groups.media.name;
-        })
-        (mkIf services.plex.enable {
-          ${users.plex.name} = mkServiceUse
r users.plex.name groups.media.name;
-        })
-        (mkIf (services.jellyfin.enable || 
services.jellyseer.enable) {
-          ${users.jellyseer.name} = mkServi
ceUser users.jellyseer.name groups.media.nam
e;
-        })
-      ];
-      groups = {
-      };
-    };
-  };
-}
 
[ BACK TO LOG ]
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET