python313Packages.traits: fix build (#373698)
[NixPkgs.git] / nixos / modules / services / web-servers / unit / default.nix
blob53c820e2947e332e74cf0b93e9a947db5382a89a
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 with lib;
10 let
11   cfg = config.services.unit;
13   configFile = pkgs.writeText "unit.json" cfg.config;
17   options = {
18     services.unit = {
19       enable = mkEnableOption "Unit App Server";
20       package = mkPackageOption pkgs "unit" { };
21       user = mkOption {
22         type = types.str;
23         default = "unit";
24         description = "User account under which unit runs.";
25       };
26       group = mkOption {
27         type = types.str;
28         default = "unit";
29         description = "Group account under which unit runs.";
30       };
31       stateDir = mkOption {
32         type = types.path;
33         default = "/var/spool/unit";
34         description = "Unit data directory.";
35       };
36       logDir = mkOption {
37         type = types.path;
38         default = "/var/log/unit";
39         description = "Unit log directory.";
40       };
41       config = mkOption {
42         type = types.str;
43         default = ''
44           {
45             "listeners": {},
46             "applications": {}
47           }
48         '';
49         example = ''
50           {
51             "listeners": {
52               "*:8300": {
53                 "application": "example-php-72"
54               }
55             },
56             "applications": {
57               "example-php-72": {
58                 "type": "php 7.2",
59                 "processes": 4,
60                 "user": "nginx",
61                 "group": "nginx",
62                 "root": "/var/www",
63                 "index": "index.php",
64                 "options": {
65                   "file": "/etc/php.d/default.ini",
66                   "admin": {
67                     "max_execution_time": "30",
68                     "max_input_time": "30",
69                     "display_errors": "off",
70                     "display_startup_errors": "off",
71                     "open_basedir": "/dev/urandom:/proc/cpuinfo:/proc/meminfo:/etc/ssl/certs:/var/www",
72                     "disable_functions": "exec,passthru,shell_exec,system"
73                   }
74                 }
75               }
76             }
77           }
78         '';
79         description = "Unit configuration in JSON format. More details here https://unit.nginx.org/configuration";
80       };
81     };
82   };
84   config = mkIf cfg.enable {
86     environment.systemPackages = [ cfg.package ];
88     systemd.tmpfiles.rules = [
89       "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
90       "d '${cfg.logDir}' 0750 ${cfg.user} ${cfg.group} - -"
91     ];
93     systemd.services.unit = {
94       description = "Unit App Server";
95       after = [ "network.target" ];
96       wantedBy = [ "multi-user.target" ];
97       preStart = ''
98         [ ! -e '${cfg.stateDir}/conf.json' ] || rm -f '${cfg.stateDir}/conf.json'
99       '';
100       postStart = ''
101         ${pkgs.curl}/bin/curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config'
102       '';
103       serviceConfig = {
104         Type = "forking";
105         PIDFile = "/run/unit/unit.pid";
106         ExecStart = ''
107           ${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \
108                                    --log '${cfg.logDir}/unit.log' --statedir '${cfg.stateDir}' --tmpdir '/tmp' \
109                                    --user ${cfg.user} --group ${cfg.group}
110         '';
111         ExecStop = ''
112           ${pkgs.curl}/bin/curl -X DELETE --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config'
113         '';
114         # Runtime directory and mode
115         RuntimeDirectory = "unit";
116         RuntimeDirectoryMode = "0750";
117         # Access write directories
118         ReadWritePaths = [
119           cfg.stateDir
120           cfg.logDir
121         ];
122         # Security
123         NoNewPrivileges = true;
124         # Sandboxing
125         ProtectSystem = "strict";
126         ProtectHome = true;
127         PrivateTmp = true;
128         PrivateDevices = true;
129         PrivateUsers = false;
130         ProtectHostname = true;
131         ProtectClock = true;
132         ProtectKernelTunables = true;
133         ProtectKernelModules = true;
134         ProtectKernelLogs = true;
135         ProtectControlGroups = true;
136         RestrictAddressFamilies = [
137           "AF_UNIX"
138           "AF_INET"
139           "AF_INET6"
140         ];
141         LockPersonality = true;
142         MemoryDenyWriteExecute = true;
143         RestrictRealtime = true;
144         RestrictSUIDSGID = true;
145         PrivateMounts = true;
146         # System Call Filtering
147         SystemCallArchitectures = "native";
148       };
149     };
151     users.users = optionalAttrs (cfg.user == "unit") {
152       unit = {
153         group = cfg.group;
154         isSystemUser = true;
155       };
156     };
158     users.groups = optionalAttrs (cfg.group == "unit") {
159       unit = { };
160     };
162   };