21 cfg = config.services.navidrome;
22 settingsFormat = pkgs.formats.json { };
26 services.navidrome = {
28 enable = mkEnableOption "Navidrome music server";
30 package = mkPackageOption pkgs "navidrome" { };
34 freeformType = settingsFormat.type;
38 default = "127.0.0.1";
39 description = "Address to run Navidrome on.";
45 description = "Port to run Navidrome on.";
52 MusicFolder = "/mnt/music";
54 description = "Configuration for Navidrome, see <https://www.navidrome.org/docs/usage/configuration-options/> for supported values.";
59 default = "navidrome";
60 description = "User under which Navidrome runs.";
65 default = "navidrome";
66 description = "Group under which Navidrome runs.";
69 openFirewall = mkOption {
72 description = "Whether to open the TCP port in the firewall";
79 inherit (lib) mkIf optional getExe;
80 WorkingDirectory = "/var/lib/navidrome";
84 tmpfiles.settings.navidromeDirs = {
85 "${cfg.settings.DataFolder or WorkingDirectory}"."d" = {
87 inherit (cfg) user group;
89 "${cfg.settings.CacheFolder or (WorkingDirectory + "/cache")}"."d" = {
91 inherit (cfg) user group;
94 services.navidrome = {
95 description = "Navidrome Media Server";
96 after = [ "network.target" ];
97 wantedBy = [ "multi-user.target" ];
100 ${getExe cfg.package} --configfile ${settingsFormat.generate "navidrome.json" cfg.settings}
104 StateDirectory = "navidrome";
105 inherit WorkingDirectory;
106 RuntimeDirectory = "navidrome";
107 RootDirectory = "/run/navidrome";
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
115 config.environment.etc."ssl/certs/ca-certificates.crt".source
116 }:/etc/ssl/certs/ca-certificates.crt"
119 ] ++ optional (cfg.settings ? MusicFolder) cfg.settings.MusicFolder;
120 CapabilityBoundingSet = "";
121 RestrictAddressFamilies = [
126 RestrictNamespaces = true;
127 PrivateDevices = true;
130 ProtectControlGroups = true;
132 ProtectKernelLogs = true;
133 ProtectKernelModules = true;
134 ProtectKernelTunables = true;
135 SystemCallArchitectures = "native";
140 RestrictRealtime = true;
141 LockPersonality = true;
142 MemoryDenyWriteExecute = true;
144 ProtectHostname = true;
149 users.users = mkIf (cfg.user == "navidrome") {
156 users.groups = mkIf (cfg.group == "navidrome") { navidrome = { }; };
158 networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.Port ];
160 meta.maintainers = with maintainers; [ fsnkty ];