1 { config, lib, pkgs, ... }:
9 nixPackage = cfg.package.out;
11 isNixAtLeast = versionAtLeast (getVersion nixPackage);
13 makeNixBuildUser = nr: {
14 name = "nixbld${toString nr}";
16 description = "Nix build user ${toString nr}";
19 For consistency with the setgid(2), setuid(2), and setgroups(2)
20 calls in `libstore/build.cc', don't add any supplementary group
23 uid = builtins.add config.ids.uids.nixbld nr;
26 extraGroups = [ "nixbld" ];
30 nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
33 assert isNixAtLeast "2.2";
38 else if isInt v then toString v
39 else if isBool v then boolToString v
40 else if isFloat v then floatToString v
41 else if isList v then toString v
42 else if isDerivation v then toString v
43 else if builtins.isPath v then toString v
44 else if isString v then v
45 else if isCoercibleToString v then toString v
46 else abort "The nix conf value: ${toPretty {} v} can not be encoded";
48 mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
50 mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
56 # WARNING: this file is generated from the nix.* options in
57 # your NixOS configuration, typically
58 # /etc/nixos/configuration.nix. Do not edit it!
59 ${mkKeyValuePairs cfg.settings}
62 checkPhase = lib.optionalString cfg.checkConfig (
63 if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
64 echo "Ignoring validation for cross-compilation"
67 echo "Validating generated nix.conf"
72 ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
73 ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
74 |& sed -e 's/^warning:/error:/' \
75 | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
80 legacyConfMappings = {
81 useSandbox = "sandbox";
84 sandboxPaths = "extra-sandbox-paths";
85 binaryCaches = "substituters";
86 trustedBinaryCaches = "trusted-substituters";
87 binaryCachePublicKeys = "trusted-public-keys";
88 autoOptimiseStore = "auto-optimise-store";
89 requireSignedBinaryCaches = "require-sigs";
90 trustedUsers = "trusted-users";
91 allowedUsers = "allowed-users";
92 systemFeatures = "system-features";
95 semanticConfType = with types;
106 description = "Nix config atom (null, bool, int, float, str, path or package)";
109 attrsOf (either confAtom (listOf confAtom));
115 (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
116 (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
117 (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
118 (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
119 ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
130 description = lib.mdDoc ''
131 Whether to enable Nix.
132 Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
137 type = types.package;
139 defaultText = literalExpression "pkgs.nix";
140 description = lib.mdDoc ''
141 This option specifies the Nix package instance to use throughout the system.
145 distributedBuilds = mkOption {
148 description = lib.mdDoc ''
149 Whether to distribute builds to the machines listed in
150 {option}`nix.buildMachines`.
154 daemonCPUSchedPolicy = mkOption {
155 type = types.enum [ "other" "batch" "idle" ];
158 description = lib.mdDoc ''
159 Nix daemon process CPU scheduling policy. This policy propagates to
160 build processes. `other` is the default scheduling
161 policy for regular tasks. The `batch` policy is
162 similar to `other`, but optimised for
163 non-interactive tasks. `idle` is for extremely
164 low-priority tasks that should only be run when no other task
167 Please note that while using the `idle` policy may
168 greatly improve responsiveness of a system performing expensive
169 builds, it may also slow down and potentially starve crucial
170 configuration updates during load.
172 `idle` may therefore be a sensible policy for
173 systems that experience only intermittent phases of high CPU load,
174 such as desktop or portable computers used interactively. Other
175 systems should use the `other` or
176 `batch` policy instead.
178 For more fine-grained resource control, please refer to
179 {manpage}`systemd.resource-control(5)` and adjust
180 {option}`systemd.services.nix-daemon` directly.
184 daemonIOSchedClass = mkOption {
185 type = types.enum [ "best-effort" "idle" ];
186 default = "best-effort";
188 description = lib.mdDoc ''
189 Nix daemon process I/O scheduling class. This class propagates to
190 build processes. `best-effort` is the default
191 class for regular tasks. The `idle` class is for
192 extremely low-priority tasks that should only perform I/O when no
195 Please note that while using the `idle` scheduling
196 class can improve responsiveness of a system performing expensive
197 builds, it might also slow down or starve crucial configuration
200 `idle` may therefore be a sensible class for
201 systems that experience only intermittent phases of high I/O load,
202 such as desktop or portable computers used interactively. Other
203 systems should use the `best-effort` class.
207 daemonIOSchedPriority = mkOption {
211 description = lib.mdDoc ''
212 Nix daemon process I/O scheduling priority. This priority propagates
213 to build processes. The supported priorities depend on the
214 scheduling policy: With idle, priorities are not used in scheduling
215 decisions. best-effort supports values in the range 0 (high) to 7
220 buildMachines = mkOption {
221 type = types.listOf (types.submodule {
223 hostName = mkOption {
225 example = "nixbuilder.example.org";
226 description = lib.mdDoc ''
227 The hostname of the build machine.
230 protocol = mkOption {
231 type = types.enum [ null "ssh" "ssh-ng" ];
234 description = lib.mdDoc ''
235 The protocol used for communicating with the build machine.
236 Use `ssh-ng` if your remote builder and your
237 local Nix version support that improved protocol.
239 Use `null` when trying to change the special localhost builder
240 without a protocol which is for example used by hydra.
244 type = types.nullOr types.str;
246 example = "x86_64-linux";
247 description = lib.mdDoc ''
248 The system type the build machine can execute derivations on.
249 Either this attribute or {var}`systems` must be
250 present, where {var}`system` takes precedence if
255 type = types.listOf types.str;
257 example = [ "x86_64-linux" "aarch64-linux" ];
258 description = lib.mdDoc ''
259 The system types the build machine can execute derivations on.
260 Either this attribute or {var}`system` must be
261 present, where {var}`system` takes precedence if
266 type = types.nullOr types.str;
269 description = lib.mdDoc ''
270 The username to log in as on the remote host. This user must be
271 able to log in and run nix commands non-interactively. It must
272 also be privileged to build derivations, so must be included in
273 {option}`nix.settings.trusted-users`.
277 type = types.nullOr types.str;
279 example = "/root/.ssh/id_buildhost_builduser";
280 description = lib.mdDoc ''
281 The path to the SSH private key with which to authenticate on
282 the build machine. The private key must not have a passphrase.
283 If null, the building user (root on NixOS machines) must have an
284 appropriate ssh configuration to log in non-interactively.
286 Note that for security reasons, this path must point to a file
287 in the local filesystem, *not* to the nix store.
293 description = lib.mdDoc ''
294 The number of concurrent jobs the build machine supports. The
295 build machine will enforce its own limits, but this allows hydra
296 to schedule better since there is no work-stealing between build
300 speedFactor = mkOption {
303 description = lib.mdDoc ''
304 The relative speed of this builder. This is an arbitrary integer
305 that indicates the speed of this builder, relative to other
306 builders. Higher is faster.
309 mandatoryFeatures = mkOption {
310 type = types.listOf types.str;
312 example = [ "big-parallel" ];
313 description = lib.mdDoc ''
314 A list of features mandatory for this builder. The builder will
315 be ignored for derivations that don't require all features in
316 this list. All mandatory features are automatically included in
317 {var}`supportedFeatures`.
320 supportedFeatures = mkOption {
321 type = types.listOf types.str;
323 example = [ "kvm" "big-parallel" ];
324 description = lib.mdDoc ''
325 A list of features supported by this builder. The builder will
326 be ignored for derivations that require features not in this
330 publicHostKey = mkOption {
331 type = types.nullOr types.str;
333 description = lib.mdDoc ''
334 The (base64-encoded) public host key of this builder. The field
335 is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
336 If null, SSH will use its regular known-hosts file when connecting.
342 description = lib.mdDoc ''
343 This option lists the machines to be used if distributed builds are
344 enabled (see {option}`nix.distributedBuilds`).
345 Nix will perform derivations on those machines via SSH by copying the
346 inputs to the Nix store on the remote machine, starting the build,
347 then copying the output back to the local Nix store.
351 # Environment variables for running Nix.
356 description = lib.mdDoc "Environment variables used by Nix.";
359 nrBuildUsers = mkOption {
361 description = lib.mdDoc ''
362 Number of `nixbld` user accounts created to
363 perform secure concurrent builds. If you receive an error
364 message saying that “all build users are currently in use”,
365 you should increase this value.
369 readOnlyStore = mkOption {
372 description = lib.mdDoc ''
373 If set, NixOS will enforce the immutability of the Nix store
374 by making {file}`/nix/store` a read-only bind
375 mount. Nix will automatically make the store writable when
381 type = types.listOf types.str;
383 "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
384 "nixos-config=/etc/nixos/configuration.nix"
385 "/nix/var/nix/profiles/per-user/root/channels"
387 description = lib.mdDoc ''
388 The default Nix expression search path, used by the Nix
389 evaluator to look up paths enclosed in angle brackets
394 checkConfig = mkOption {
397 description = lib.mdDoc ''
398 If enabled, checks that Nix can parse the generated nix.conf.
402 checkAllErrors = mkOption {
405 description = lib.mdDoc ''
406 If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
410 registry = mkOption {
411 type = types.attrsOf (types.submodule (
413 referenceAttrs = with types; attrsOf (oneOf [
420 { config, name, ... }:
424 type = referenceAttrs;
425 example = { type = "indirect"; id = "nixpkgs"; };
426 description = lib.mdDoc "The flake reference to be rewritten.";
429 type = referenceAttrs;
430 example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
431 description = lib.mdDoc "The flake reference {option}`from` is rewritten to.";
434 type = types.nullOr types.attrs;
436 example = literalExpression "nixpkgs";
437 description = lib.mdDoc ''
438 The flake input {option}`from` is rewritten to.
444 description = lib.mdDoc ''
445 Whether the {option}`from` reference needs to match exactly. If set,
446 a {option}`from` reference like `nixpkgs` does not
447 match with a reference like `nixpkgs/nixos-20.03`.
452 from = mkDefault { type = "indirect"; id = name; };
453 to = mkIf (config.flake != null) (mkDefault (
456 path = config.flake.outPath;
458 (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
465 description = lib.mdDoc ''
466 A system-wide flake registry.
470 extraOptions = mkOption {
475 keep-derivations = true
477 description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
480 settings = mkOption {
481 type = types.submodule {
482 freeformType = semanticConfType;
485 max-jobs = mkOption {
486 type = types.either types.int (types.enum [ "auto" ]);
489 description = lib.mdDoc ''
490 This option defines the maximum number of jobs that Nix will try to
491 build in parallel. The default is auto, which means it will use all
492 available logical cores. It is recommend to set it to the total
493 number of logical cores in your system (e.g., 16 for two CPUs with 4
494 cores each and hyper-threading).
498 auto-optimise-store = mkOption {
502 description = lib.mdDoc ''
503 If set to true, Nix automatically detects files in the store that have
504 identical contents, and replaces them with hard links to a single copy.
505 This saves disk space. If set to false (the default), you can still run
506 nix-store --optimise to get rid of duplicate files.
514 description = lib.mdDoc ''
515 This option defines the maximum number of concurrent tasks during
516 one build. It affects, e.g., -j option for make.
517 The special value 0 means that the builder should use all
518 available CPU cores in the system. Some builds may become
519 non-deterministic with this option; use with care! Packages will
520 only be affected if enableParallelBuilding is set for them.
525 type = types.either types.bool (types.enum [ "relaxed" ]);
527 description = lib.mdDoc ''
528 If set, Nix will perform builds in a sandboxed environment that it
529 will set up automatically for each build. This prevents impurities
530 in builds by disallowing access to dependencies outside of the Nix
531 store by using network and mount namespaces in a chroot environment.
532 This is enabled by default even though it has a possible performance
533 impact due to the initial setup time of a sandbox for each build. It
534 doesn't affect derivation hashes, so changing this option will not
535 trigger a rebuild of packages.
539 extra-sandbox-paths = mkOption {
540 type = types.listOf types.str;
542 example = [ "/dev" "/proc" ];
543 description = lib.mdDoc ''
544 Directories from the host filesystem to be included
549 substituters = mkOption {
550 type = types.listOf types.str;
551 description = lib.mdDoc ''
552 List of binary cache URLs used to obtain pre-built binaries
555 By default https://cache.nixos.org/ is added.
559 trusted-substituters = mkOption {
560 type = types.listOf types.str;
562 example = [ "https://hydra.nixos.org/" ];
563 description = lib.mdDoc ''
564 List of binary cache URLs that non-root users can use (in
565 addition to those specified using
566 {option}`nix.settings.substituters`) by passing
567 `--option binary-caches` to Nix commands.
571 require-sigs = mkOption {
574 description = lib.mdDoc ''
575 If enabled (the default), Nix will only download binaries from binary caches if
576 they are cryptographically signed with any of the keys listed in
577 {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
578 required nor checked, so it's strongly recommended that you use only
579 trustworthy caches and https to prevent man-in-the-middle attacks.
583 trusted-public-keys = mkOption {
584 type = types.listOf types.str;
585 example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
586 description = lib.mdDoc ''
587 List of public keys used to sign binary caches. If
588 {option}`nix.settings.trusted-public-keys` is enabled,
589 then Nix will use a binary from a binary cache if and only
590 if it is signed by *any* of the keys
591 listed here. By default, only the key for
592 `cache.nixos.org` is included.
596 trusted-users = mkOption {
597 type = types.listOf types.str;
598 default = [ "root" ];
599 example = [ "root" "alice" "@wheel" ];
600 description = lib.mdDoc ''
601 A list of names of users that have additional rights when
602 connecting to the Nix daemon, such as the ability to specify
603 additional binary caches, or to import unsigned NARs. You
604 can also specify groups by prefixing them with
606 `@wheel` means all users in the wheel
611 system-features = mkOption {
612 type = types.listOf types.str;
613 example = [ "kvm" "big-parallel" "gccarch-skylake" ];
614 description = lib.mdDoc ''
615 The set of features supported by the machine. Derivations
616 can express dependencies on system features through the
617 `requiredSystemFeatures` attribute.
619 By default, pseudo-features `nixos-test`, `benchmark`,
620 and `big-parallel` used in Nixpkgs are set, `kvm`
621 is also included in it is avaliable.
625 allowed-users = mkOption {
626 type = types.listOf types.str;
628 example = [ "@wheel" "@builders" "alice" "bob" ];
629 description = lib.mdDoc ''
630 A list of names of users (separated by whitespace) that are
631 allowed to connect to the Nix daemon. As with
632 {option}`nix.settings.trusted-users`, you can specify groups by
633 prefixing them with `@`. Also, you can
634 allow all users by specifying `*`. The
635 default is `*`. Note that trusted users are
636 always allowed to connect.
642 example = literalExpression ''
647 system-features = [ "big-parallel" "kvm" "recursive-nix" ];
648 sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
651 description = lib.mdDoc ''
652 Configuration for Nix, see
653 <https://nixos.org/manual/nix/stable/#sec-conf-file> or
654 {manpage}`nix.conf(5)` for avalaible options.
655 The value declared here will be translated directly to the key-value pairs Nix expects.
657 You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
658 to view the current value. By default it is empty.
660 Nix configurations defined under {option}`nix.*` will be translated and applied to this
661 option. In addition, configuration specified in {option}`nix.extraOptions` which will be appended
662 verbatim to the resulting config file.
669 ###### implementation
671 config = mkIf cfg.enable {
672 environment.systemPackages =
677 ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
679 environment.etc."nix/nix.conf".source = nixConf;
681 environment.etc."nix/registry.json".text = builtins.toJSON {
683 flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
686 # List of machines for distributed Nix builds in the format
687 # expected by build-remote.pl.
688 environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
692 (concatStringsSep " " ([
693 "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
694 (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
695 (if machine.sshKey != null then machine.sshKey else "-")
696 (toString machine.maxJobs)
697 (toString machine.speedFactor)
698 (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
699 in if (res == []) then "-" else (concatStringsSep "," res))
700 (let res = machine.mandatoryFeatures;
701 in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
703 ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
710 let badMachine = m: m.system == null && m.systems == [ ];
714 assertion = !(any badMachine cfg.buildMachines);
716 At least one system type (via <varname>system</varname> or
717 <varname>systems</varname>) must be set for every build machine.
718 Invalid machine specifications:
720 (concatStringsSep "\n "
722 (filter (badMachine) cfg.buildMachines)));
726 systemd.packages = [ nixPackage ];
728 # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
729 # systemd.tmpfiles.packages = [ nixPackage ];
731 # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
732 systemd.tmpfiles.rules = [
733 "d /nix/var/nix/daemon-socket 0755 root root - -"
736 systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
738 systemd.services.nix-daemon =
740 path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
741 ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
743 environment = cfg.envVars
744 // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
745 // config.networking.proxy.envVars;
747 unitConfig.RequiresMountsFor = "/nix/store";
751 CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
752 IOSchedulingClass = cfg.daemonIOSchedClass;
753 IOSchedulingPriority = cfg.daemonIOSchedPriority;
754 LimitNOFILE = 1048576;
757 restartTriggers = [ nixConf ];
759 # `stopIfChanged = false` changes to switch behavior
760 # from stop -> update units -> start
761 # to update units -> restart
763 # The `stopIfChanged` setting therefore controls a trade-off between a
764 # more predictable lifecycle, which runs the correct "version" of
765 # the `ExecStop` line, and on the other hand the availability of
766 # sockets during the switch, as the effectiveness of the stop operation
767 # depends on the socket being stopped as well.
769 # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
770 # to keep the socket up and available. This is important for machines
771 # that run Nix-based services, such as automated build, test, and deploy
772 # services, that expect the daemon socket to be available at all times.
774 # Notably, the Nix client does not retry on failure to connect to the
775 # daemon socket, and the in-process RemoteStore instance will disable
776 # itself. This makes retries infeasible even for services that are
777 # aware of the issue. Failure to connect can affect not only new client
778 # processes, but also new RemoteStore instances in existing processes,
779 # as well as existing RemoteStore instances that have not saturated
780 # their connection pool.
782 # Also note that `stopIfChanged = true` does not kill existing
783 # connection handling daemons, as one might wish to happen before a
784 # breaking Nix upgrade (which is rare). The daemon forks that handle
785 # the individual connections split off into their own sessions, causing
786 # them not to be stopped by systemd.
787 # If a Nix upgrade does require all existing daemon processes to stop,
788 # nix-daemon must do so on its own accord, and only when the new version
789 # starts and detects that Nix's persistent state needs an upgrade.
790 stopIfChanged = false;
794 # Set up the environment variables for running Nix.
795 environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
797 environment.extraInit =
799 if [ -e "$HOME/.nix-defexpr/channels" ]; then
800 export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
804 nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs));
806 users.users = nixbldUsers;
808 services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
810 system.activationScripts.nix = stringAfter [ "etc" "users" ]
812 install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
814 # Subscribe the root user to the NixOS channel by default.
815 if [ ! -e "/root/.nix-channels" ]; then
816 echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
820 # Legacy configuration conversion.
821 nix.settings = mkMerge [
823 trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
824 substituters = mkAfter [ "https://cache.nixos.org/" ];
826 system-features = mkDefault (
827 [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
828 optionals (pkgs.hostPlatform ? gcc.arch) (
829 # a builder can run code for `gcc.arch` and inferior architectures
830 [ "gccarch-${pkgs.hostPlatform.gcc.arch}" ] ++
831 map (x: "gccarch-${x}") systems.architectures.inferiors.${pkgs.hostPlatform.gcc.arch}
836 (mkIf (!cfg.distributedBuilds) { builders = null; })
838 (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })