1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.navidrome;
7 settingsFormat = pkgs.formats.json {};
8in {
9 options = {
10 services.navidrome = {
11
12 enable = mkEnableOption pkgs.navidrome.meta.description;
13
14 settings = mkOption rec {
15 type = settingsFormat.type;
16 apply = recursiveUpdate default;
17 default = {
18 Address = "127.0.0.1";
19 Port = 4533;
20 };
21 example = {
22 MusicFolder = "/mnt/music";
23 };
24 description = ''
25 Configuration for Navidrome, see <link xlink:href="https://www.navidrome.org/docs/usage/configuration-options/"/> for supported values.
26 '';
27 };
28
29 };
30 };
31
32 config = mkIf cfg.enable {
33 systemd.services.navidrome = {
34 description = "Navidrome Media Server";
35 after = [ "network.target" ];
36 wantedBy = [ "multi-user.target" ];
37 serviceConfig = {
38 ExecStart = ''
39 ${pkgs.navidrome}/bin/navidrome --configfile ${settingsFormat.generate "navidrome.json" cfg.settings}
40 '';
41 DynamicUser = true;
42 StateDirectory = "navidrome";
43 WorkingDirectory = "/var/lib/navidrome";
44 RuntimeDirectory = "navidrome";
45 RootDirectory = "/run/navidrome";
46 ReadWritePaths = "";
47 BindReadOnlyPaths = [
48 builtins.storeDir
49 ] ++ lib.optional (cfg.settings ? MusicFolder) cfg.settings.MusicFolder;
50 CapabilityBoundingSet = "";
51 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
52 RestrictNamespaces = true;
53 PrivateDevices = true;
54 PrivateUsers = true;
55 ProtectClock = true;
56 ProtectControlGroups = true;
57 ProtectHome = true;
58 ProtectKernelLogs = true;
59 ProtectKernelModules = true;
60 ProtectKernelTunables = true;
61 SystemCallArchitectures = "native";
62 SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
63 RestrictRealtime = true;
64 LockPersonality = true;
65 MemoryDenyWriteExecute = true;
66 UMask = "0066";
67 ProtectHostname = true;
68 };
69 };
70 };
71}