8 cfg = config.services.polaris;
9 settingsFormat = pkgs.formats.toml {};
14 enable = mkEnableOption "Polaris Music Server";
16 package = mkPackageOption pkgs "polaris" { };
21 description = "User account under which Polaris runs.";
27 description = "Group under which Polaris is run.";
30 extraGroups = mkOption {
31 type = types.listOf types.str;
33 description = "Polaris' auxiliary groups.";
34 example = literalExpression ''["media" "music"]'';
41 The port which the Polaris REST api and web UI should listen to.
42 Note: polaris is hardcoded to listen to the hostname "0.0.0.0".
47 type = settingsFormat.type;
50 Contents for the TOML Polaris config, applied each start.
51 Although poorly documented, an example may be found here:
52 [test-config.toml](https://github.com/agersant/polaris/blob/374d0ca56fc0a466d797a4b252e2078607476797/test-data/config.toml)
54 example = literalExpression ''
56 settings.reindex_every_n_seconds = 7*24*60*60; # weekly, default is 1800
57 settings.album_art_pattern =
58 "(cover|front|folder)\.(jpeg|jpg|png|bmp|gif)";
62 source = "/mnt/nas/music";
66 source = "/home/my_user/Music";
73 openFirewall = mkOption {
77 Open the configured port in the firewall.
83 config = mkIf cfg.enable {
84 systemd.services.polaris = {
85 description = "Polaris Music Server";
86 after = [ "network.target" ];
87 wantedBy = [ "multi-user.target" ];
93 SupplementaryGroups = cfg.extraGroups;
94 StateDirectory = "polaris";
95 CacheDirectory = "polaris";
96 ExecStart = escapeShellArgs ([
97 "${cfg.package}/bin/polaris"
100 "--database" "/var/lib/${StateDirectory}/db.sqlite"
101 "--cache" "/var/cache/${CacheDirectory}"
102 ] ++ optionals (cfg.settings != {}) [
103 "--config" (settingsFormat.generate "polaris-config.toml" cfg.settings)
105 Restart = "on-failure";
109 #NoNewPrivileges = true; # implied by DynamicUser
110 #RemoveIPC = true; # implied by DynamicUser
112 AmbientCapabilities = "";
113 CapabilityBoundingSet = "";
117 LockPersonality = true;
119 #PrivateTmp = true; # implied by DynamicUser
120 PrivateDevices = true;
124 ProtectControlGroups = true;
125 ProtectHostname = true;
126 ProtectKernelLogs = true;
127 ProtectKernelModules = true;
128 ProtectKernelTunables = true;
130 RestrictNamespaces = true;
131 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
132 RestrictRealtime = true;
133 #RestrictSUIDSGID = true; # implied by DynamicUser
135 SystemCallArchitectures = "native";
136 SystemCallErrorNumber = "EPERM";
139 "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid"
144 networking.firewall = mkIf cfg.openFirewall {
145 allowedTCPPorts = [ cfg.port ];
150 meta.maintainers = with maintainers; [ pbsds ];