grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / misc / polaris.nix
blob4ac99eaad38492ec8fbf7f5ee6832bee1d7e7964
1 { config
2 , pkgs
3 , lib
4 , ...}:
6 with lib;
7 let
8   cfg = config.services.polaris;
9   settingsFormat = pkgs.formats.toml {};
12   options = {
13     services.polaris = {
14       enable = mkEnableOption "Polaris Music Server";
16       package = mkPackageOption pkgs "polaris" { };
18       user = mkOption {
19         type = types.str;
20         default = "polaris";
21         description = "User account under which Polaris runs.";
22       };
24       group = mkOption {
25         type = types.str;
26         default = "polaris";
27         description = "Group under which Polaris is run.";
28       };
30       extraGroups = mkOption {
31         type = types.listOf types.str;
32         default = [];
33         description = "Polaris' auxiliary groups.";
34         example = literalExpression ''["media" "music"]'';
35       };
37       port = mkOption {
38         type = types.port;
39         default = 5050;
40         description = ''
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".
43         '';
44       };
46       settings = mkOption {
47         type = settingsFormat.type;
48         default = {};
49         description = ''
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)
53         '';
54         example = literalExpression ''
55           {
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)";
59             mount_dirs = [
60               {
61                 name = "NAS";
62                 source = "/mnt/nas/music";
63               }
64               {
65                 name = "Local";
66                 source = "/home/my_user/Music";
67               }
68             ];
69           }
70         '';
71       };
73       openFirewall = mkOption {
74         type = types.bool;
75         default = false;
76         description = ''
77           Open the configured port in the firewall.
78         '';
79       };
80     };
81   };
83   config = mkIf cfg.enable {
84     systemd.services.polaris = {
85       description = "Polaris Music Server";
86       after = [ "network.target" ];
87       wantedBy = [ "multi-user.target" ];
89       serviceConfig = rec {
90         User = cfg.user;
91         Group = cfg.group;
92         DynamicUser = true;
93         SupplementaryGroups = cfg.extraGroups;
94         StateDirectory = "polaris";
95         CacheDirectory = "polaris";
96         ExecStart = escapeShellArgs ([
97           "${cfg.package}/bin/polaris"
98           "--foreground"
99           "--port" cfg.port
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)
104         ]);
105         Restart = "on-failure";
107         # Security options:
109         #NoNewPrivileges = true; # implied by DynamicUser
110         #RemoveIPC = true; # implied by DynamicUser
112         AmbientCapabilities = "";
113         CapabilityBoundingSet = "";
115         DeviceAllow = "";
117         LockPersonality = true;
119         #PrivateTmp = true; # implied by DynamicUser
120         PrivateDevices = true;
121         PrivateUsers = true;
123         ProtectClock = 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";
137         SystemCallFilter = [
138           "@system-service"
139           "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid"
140         ];
141       };
142     };
144     networking.firewall = mkIf cfg.openFirewall {
145       allowedTCPPorts = [ cfg.port ];
146     };
148   };
150   meta.maintainers = with maintainers; [ pbsds ];