2 Declares what makes the nix-daemon work on systemd.
5 - nixos/modules/config/nix.nix: the nix.conf
6 - nixos/modules/config/nix-remote-build.nix: the nix.conf
8 { config, lib, pkgs, ... }:
16 nixPackage = cfg.package.out;
18 isNixAtLeast = versionAtLeast (getVersion nixPackage);
20 makeNixBuildUser = nr: {
21 name = "nixbld${toString nr}";
23 description = "Nix build user ${toString nr}";
26 For consistency with the setgid(2), setuid(2), and setgroups(2)
27 calls in `libstore/build.cc', don't add any supplementary group
30 uid = builtins.add config.ids.uids.nixbld nr;
33 extraGroups = [ "nixbld" ];
37 nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
43 (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
44 (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; })
45 (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
58 Whether to enable Nix.
59 Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
66 defaultText = literalExpression "pkgs.nix";
68 This option specifies the Nix package instance to use throughout the system.
72 daemonCPUSchedPolicy = mkOption {
73 type = types.enum [ "other" "batch" "idle" ];
77 Nix daemon process CPU scheduling policy. This policy propagates to
78 build processes. `other` is the default scheduling
79 policy for regular tasks. The `batch` policy is
80 similar to `other`, but optimised for
81 non-interactive tasks. `idle` is for extremely
82 low-priority tasks that should only be run when no other task
85 Please note that while using the `idle` policy may
86 greatly improve responsiveness of a system performing expensive
87 builds, it may also slow down and potentially starve crucial
88 configuration updates during load.
90 `idle` may therefore be a sensible policy for
91 systems that experience only intermittent phases of high CPU load,
92 such as desktop or portable computers used interactively. Other
93 systems should use the `other` or
94 `batch` policy instead.
96 For more fine-grained resource control, please refer to
97 {manpage}`systemd.resource-control(5)` and adjust
98 {option}`systemd.services.nix-daemon` directly.
102 daemonIOSchedClass = mkOption {
103 type = types.enum [ "best-effort" "idle" ];
104 default = "best-effort";
107 Nix daemon process I/O scheduling class. This class propagates to
108 build processes. `best-effort` is the default
109 class for regular tasks. The `idle` class is for
110 extremely low-priority tasks that should only perform I/O when no
113 Please note that while using the `idle` scheduling
114 class can improve responsiveness of a system performing expensive
115 builds, it might also slow down or starve crucial configuration
118 `idle` may therefore be a sensible class for
119 systems that experience only intermittent phases of high I/O load,
120 such as desktop or portable computers used interactively. Other
121 systems should use the `best-effort` class.
125 daemonIOSchedPriority = mkOption {
130 Nix daemon process I/O scheduling priority. This priority propagates
131 to build processes. The supported priorities depend on the
132 scheduling policy: With idle, priorities are not used in scheduling
133 decisions. best-effort supports values in the range 0 (high) to 7
138 # Environment variables for running Nix.
143 description = "Environment variables used by Nix.";
146 nrBuildUsers = mkOption {
149 Number of `nixbld` user accounts created to
150 perform secure concurrent builds. If you receive an error
151 message saying that “all build users are currently in use”,
152 you should increase this value.
159 ###### implementation
161 config = mkIf cfg.enable {
162 environment.systemPackages =
167 ++ optional (config.programs.bash.completion.enable) pkgs.nix-bash-completions;
169 systemd.packages = [ nixPackage ];
171 systemd.tmpfiles = mkMerge [
172 (mkIf (isNixAtLeast "2.8") {
173 packages = [ nixPackage ];
175 (mkIf (!isNixAtLeast "2.8") {
177 "d /nix/var/nix/daemon-socket 0755 root root - -"
182 systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
184 systemd.services.nix-daemon =
186 path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
187 ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
189 environment = cfg.envVars
190 // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
191 // config.networking.proxy.envVars;
193 unitConfig.RequiresMountsFor = "/nix/store";
197 CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
198 IOSchedulingClass = cfg.daemonIOSchedClass;
199 IOSchedulingPriority = cfg.daemonIOSchedPriority;
200 LimitNOFILE = 1048576;
204 restartTriggers = [ config.environment.etc."nix/nix.conf".source ];
206 # `stopIfChanged = false` changes to switch behavior
207 # from stop -> update units -> start
208 # to update units -> restart
210 # The `stopIfChanged` setting therefore controls a trade-off between a
211 # more predictable lifecycle, which runs the correct "version" of
212 # the `ExecStop` line, and on the other hand the availability of
213 # sockets during the switch, as the effectiveness of the stop operation
214 # depends on the socket being stopped as well.
216 # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
217 # to keep the socket up and available. This is important for machines
218 # that run Nix-based services, such as automated build, test, and deploy
219 # services, that expect the daemon socket to be available at all times.
221 # Notably, the Nix client does not retry on failure to connect to the
222 # daemon socket, and the in-process RemoteStore instance will disable
223 # itself. This makes retries infeasible even for services that are
224 # aware of the issue. Failure to connect can affect not only new client
225 # processes, but also new RemoteStore instances in existing processes,
226 # as well as existing RemoteStore instances that have not saturated
227 # their connection pool.
229 # Also note that `stopIfChanged = true` does not kill existing
230 # connection handling daemons, as one might wish to happen before a
231 # breaking Nix upgrade (which is rare). The daemon forks that handle
232 # the individual connections split off into their own sessions, causing
233 # them not to be stopped by systemd.
234 # If a Nix upgrade does require all existing daemon processes to stop,
235 # nix-daemon must do so on its own accord, and only when the new version
236 # starts and detects that Nix's persistent state needs an upgrade.
237 stopIfChanged = false;
241 # Set up the environment variables for running Nix.
242 environment.sessionVariables = cfg.envVars;
244 nix.nrBuildUsers = mkDefault (
245 if cfg.settings.auto-allocate-uids or false then 0
246 else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
249 users.users = nixbldUsers;
251 services.displayManager.hiddenUsers = attrNames nixbldUsers;
253 # Legacy configuration conversion.
254 nix.settings = mkMerge [
255 (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })