me like nix
1{ inputs, ... }:
2
3let
4 jellyfinKodiSyncQueue = inputs.nixpkgs.legacyPackages.x86_64-linux.fetchzip {
5 url = "https://repo.jellyfin.org/releases/plugin/kodi-sync-queue/kodi-sync-queue_15.0.0.0.zip";
6 stripRoot = false;
7 hash = "sha256-xtlG3UQ/WClt/Hvxe+oId2CeJ+PWMDXBUJXh5+k+mZQ=";
8 };
9in
10{
11 flake.modules.nixos.media-server =
12 { pkgs, config, lib, ... }:
13 {
14 services.flaresolverr.enable = true;
15
16 services.immich = {
17 enable = true;
18 mediaLocation = "/mnt/storage2/immich";
19 host = "0.0.0.0";
20 openFirewall = true;
21 };
22
23 # Immich uses PostgreSQL via Unix socket; avoid conflicting with lbdt-postgres on TCP/5432.
24 services.postgresql.settings.listen_addresses = lib.mkForce "";
25
26 systemd.tmpfiles.rules = [
27 "d /mnt/storage2/immich 0750 immich immich -"
28 ];
29
30 age.secrets.wireguard.file = ../secrets/wireguard.age;
31
32 nixarr = {
33 enable = true;
34 mediaDir = "/mnt/storage1/nixarr/media";
35 vpn = {
36 enable = true;
37 wgConf = config.age.secrets.wireguard.path;
38 };
39
40 jellyfin = {
41 enable = true;
42 openFirewall = true;
43 };
44
45 transmission = {
46 enable = true;
47 vpn.enable = true;
48 peerPort = 51413;
49 };
50 sabnzbd = {
51 enable = true;
52 vpn.enable = true;
53 openFirewall = true;
54 };
55
56 prowlarr.enable = true;
57 radarr.enable = true;
58 sonarr.enable = true;
59 seerr = {
60 enable = true;
61 openFirewall = true;
62 };
63
64 recyclarr = {
65 enable = true;
66 configuration = {
67 sonarr = {
68 series = {
69 base_url = "http://localhost:8989";
70 api_key = "!env_var SONARR_API_KEY";
71 quality_definition = {
72 type = "series";
73 };
74 delete_old_custom_formats = true;
75 custom_formats = [
76 {
77 trash_ids = [
78 "85c61753df5da1fb2aab6f2a47426b09"
79 "9c11cd3f07101cdba90a2d81cf0e56b4"
80 ];
81 assign_scores_to = [
82 {
83 name = "WEB-DL (1080p)";
84 score = -10000;
85 }
86 ];
87 }
88 ];
89 };
90 };
91 radarr = {
92 movies = {
93 base_url = "http://localhost:7878";
94 api_key = "!env_var RADARR_API_KEY";
95 quality_definition = {
96 type = "movie";
97 };
98 delete_old_custom_formats = true;
99 custom_formats = [
100 {
101 trash_ids = [
102 "570bc9ebecd92723d2d21500f4be314c"
103 "eca37840c13c6ef2dd0262b141a5482f"
104 ];
105 assign_scores_to = [
106 {
107 name = "HD Bluray + WEB";
108 score = 25;
109 }
110 ];
111 }
112 ];
113 };
114 };
115 };
116 };
117 };
118
119 # Avoid jellyfin blocking shutdown for 2 minutes
120 systemd.services.jellyfin.serviceConfig.TimeoutStopSec = 10;
121
122 # Install Kodi Sync Queue plugin into Jellyfin
123 systemd.services.jellyfin.serviceConfig.ExecStartPre =
124 let
125 pluginDir = "/data/.state/nixarr/jellyfin/data/plugins/Kodi Sync Queue/15.0.0.0";
126 in
127 pkgs.writeShellScript "install-jellyfin-plugins" ''
128 mkdir -p "${pluginDir}"
129 cp -f ${jellyfinKodiSyncQueue}/*.dll ${jellyfinKodiSyncQueue}/meta.json "${pluginDir}/"
130 '';
131 };
132}