vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / audio / navidrome.nix
blob06d2d174a4df3a576b73c5c817202645adf6bb3d
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
9   inherit (lib)
10     mkEnableOption
11     mkPackageOption
12     mkOption
13     maintainers
14     ;
15   inherit (lib.types)
16     bool
17     port
18     str
19     submodule
20     ;
21   cfg = config.services.navidrome;
22   settingsFormat = pkgs.formats.json { };
25   options = {
26     services.navidrome = {
28       enable = mkEnableOption "Navidrome music server";
30       package = mkPackageOption pkgs "navidrome" { };
32       settings = mkOption {
33         type = submodule {
34           freeformType = settingsFormat.type;
36           options = {
37             Address = mkOption {
38               default = "127.0.0.1";
39               description = "Address to run Navidrome on.";
40               type = str;
41             };
43             Port = mkOption {
44               default = 4533;
45               description = "Port to run Navidrome on.";
46               type = port;
47             };
48           };
49         };
50         default = { };
51         example = {
52           MusicFolder = "/mnt/music";
53         };
54         description = "Configuration for Navidrome, see <https://www.navidrome.org/docs/usage/configuration-options/> for supported values.";
55       };
57       user = mkOption {
58         type = str;
59         default = "navidrome";
60         description = "User under which Navidrome runs.";
61       };
63       group = mkOption {
64         type = str;
65         default = "navidrome";
66         description = "Group under which Navidrome runs.";
67       };
69       openFirewall = mkOption {
70         type = bool;
71         default = false;
72         description = "Whether to open the TCP port in the firewall";
73       };
74     };
75   };
77   config =
78     let
79       inherit (lib) mkIf optional getExe;
80       WorkingDirectory = "/var/lib/navidrome";
81     in
82     mkIf cfg.enable {
83       systemd = {
84         tmpfiles.settings.navidromeDirs = {
85           "${cfg.settings.DataFolder or WorkingDirectory}"."d" = {
86             mode = "700";
87             inherit (cfg) user group;
88           };
89           "${cfg.settings.CacheFolder or (WorkingDirectory + "/cache")}"."d" = {
90             mode = "700";
91             inherit (cfg) user group;
92           };
93         };
94         services.navidrome = {
95           description = "Navidrome Media Server";
96           after = [ "network.target" ];
97           wantedBy = [ "multi-user.target" ];
98           serviceConfig = {
99             ExecStart = ''
100               ${getExe cfg.package} --configfile ${settingsFormat.generate "navidrome.json" cfg.settings}
101             '';
102             User = cfg.user;
103             Group = cfg.group;
104             StateDirectory = "navidrome";
105             inherit WorkingDirectory;
106             RuntimeDirectory = "navidrome";
107             RootDirectory = "/run/navidrome";
108             ReadWritePaths = "";
109             BindPaths =
110               optional (cfg.settings ? DataFolder) cfg.settings.DataFolder
111               ++ optional (cfg.settings ? CacheFolder) cfg.settings.CacheFolder;
112             BindReadOnlyPaths = [
113               # navidrome uses online services to download additional album metadata / covers
114               "${
115                 config.environment.etc."ssl/certs/ca-certificates.crt".source
116               }:/etc/ssl/certs/ca-certificates.crt"
117               builtins.storeDir
118               "/etc"
119             ] ++ optional (cfg.settings ? MusicFolder) cfg.settings.MusicFolder;
120             CapabilityBoundingSet = "";
121             RestrictAddressFamilies = [
122               "AF_UNIX"
123               "AF_INET"
124               "AF_INET6"
125             ];
126             RestrictNamespaces = true;
127             PrivateDevices = true;
128             PrivateUsers = true;
129             ProtectClock = true;
130             ProtectControlGroups = true;
131             ProtectHome = true;
132             ProtectKernelLogs = true;
133             ProtectKernelModules = true;
134             ProtectKernelTunables = true;
135             SystemCallArchitectures = "native";
136             SystemCallFilter = [
137               "@system-service"
138               "~@privileged"
139             ];
140             RestrictRealtime = true;
141             LockPersonality = true;
142             MemoryDenyWriteExecute = true;
143             UMask = "0066";
144             ProtectHostname = true;
145           };
146         };
147       };
149       users.users = mkIf (cfg.user == "navidrome") {
150         navidrome = {
151           inherit (cfg) group;
152           isSystemUser = true;
153         };
154       };
156       users.groups = mkIf (cfg.group == "navidrome") { navidrome = { }; };
158       networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.Port ];
159     };
160   meta.maintainers = with maintainers; [ fsnkty ];