at 18.09-beta 5.1 kB view raw
1<section xmlns="http://docbook.org/ns/docbook" 2 xmlns:xlink="http://www.w3.org/1999/xlink" 3 xmlns:xi="http://www.w3.org/2001/XInclude" 4 version="5.0" 5 xml:id="sec-modularity"> 6 <title>Modularity</title> 7 8 <para> 9 The NixOS configuration mechanism is modular. If your 10 <filename>configuration.nix</filename> becomes too big, you can split it into 11 multiple files. Likewise, if you have multiple NixOS configurations (e.g. for 12 different computers) with some commonality, you can move the common 13 configuration into a shared file. 14 </para> 15 16 <para> 17 Modules have exactly the same syntax as 18 <filename>configuration.nix</filename>. In fact, 19 <filename>configuration.nix</filename> is itself a module. You can use other 20 modules by including them from <filename>configuration.nix</filename>, e.g.: 21<programlisting> 22{ config, pkgs, ... }: 23 24{ imports = [ ./vpn.nix ./kde.nix ]; 25 <xref linkend="opt-services.httpd.enable"/> = true; 26 <xref linkend="opt-environment.systemPackages"/> = [ pkgs.emacs ]; 27 <replaceable>...</replaceable> 28} 29</programlisting> 30 Here, we include two modules from the same directory, 31 <filename>vpn.nix</filename> and <filename>kde.nix</filename>. The latter 32 might look like this: 33<programlisting> 34{ config, pkgs, ... }: 35 36{ <xref linkend="opt-services.xserver.enable"/> = true; 37 <xref linkend="opt-services.xserver.displayManager.sddm.enable"/> = true; 38 <xref linkend="opt-services.xserver.desktopManager.plasma5.enable"/> = true; 39} 40</programlisting> 41 Note that both <filename>configuration.nix</filename> and 42 <filename>kde.nix</filename> define the option 43 <xref linkend="opt-environment.systemPackages"/>. When multiple modules 44 define an option, NixOS will try to <emphasis>merge</emphasis> the 45 definitions. In the case of <xref linkend="opt-environment.systemPackages"/>, 46 that’s easy: the lists of packages can simply be concatenated. The value in 47 <filename>configuration.nix</filename> is merged last, so for list-type 48 options, it will appear at the end of the merged list. If you want it to 49 appear first, you can use <varname>mkBefore</varname>: 50<programlisting> 51<xref linkend="opt-boot.kernelModules"/> = mkBefore [ "kvm-intel" ]; 52</programlisting> 53 This causes the <literal>kvm-intel</literal> kernel module to be loaded 54 before any other kernel modules. 55 </para> 56 57 <para> 58 For other types of options, a merge may not be possible. For instance, if two 59 modules define <xref linkend="opt-services.httpd.adminAddr"/>, 60 <command>nixos-rebuild</command> will give an error: 61<screen> 62The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. 63</screen> 64 When that happens, it’s possible to force one definition take precedence 65 over the others: 66<programlisting> 67<xref linkend="opt-services.httpd.adminAddr"/> = pkgs.lib.mkForce "bob@example.org"; 68</programlisting> 69 </para> 70 71 <para> 72 When using multiple modules, you may need to access configuration values 73 defined in other modules. This is what the <varname>config</varname> function 74 argument is for: it contains the complete, merged system configuration. That 75 is, <varname>config</varname> is the result of combining the configurations 76 returned by every module 77 <footnote xml:id="footnote-nix-is-lazy"> 78 <para> 79 If you’re wondering how it’s possible that the (indirect) 80 <emphasis>result</emphasis> of a function is passed as an 81 <emphasis>input</emphasis> to that same function: that’s because Nix is a 82 “lazy” language — it only computes values when they are needed. This 83 works as long as no individual configuration value depends on itself. 84 </para> 85 </footnote> 86 . For example, here is a module that adds some packages to 87 <xref linkend="opt-environment.systemPackages"/> only if 88 <xref linkend="opt-services.xserver.enable"/> is set to 89 <literal>true</literal> somewhere else: 90<programlisting> 91{ config, pkgs, ... }: 92 93{ <xref linkend="opt-environment.systemPackages"/> = 94 if config.<xref linkend="opt-services.xserver.enable"/> then 95 [ pkgs.firefox 96 pkgs.thunderbird 97 ] 98 else 99 [ ]; 100} 101</programlisting> 102 </para> 103 104 <para> 105 With multiple modules, it may not be obvious what the final value of a 106 configuration option is. The command <option>nixos-option</option> allows you 107 to find out: 108<screen> 109$ nixos-option <xref linkend="opt-services.xserver.enable"/> 110true 111 112$ nixos-option <xref linkend="opt-boot.kernelModules"/> 113[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ] 114</screen> 115 Interactive exploration of the configuration is possible using 116 <command 117xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>, 118 a read-eval-print loop for Nix expressions. It’s not installed by default; 119 run <literal>nix-env -i nix-repl</literal> to get it. A typical use: 120<screen> 121$ nix-repl '&lt;nixpkgs/nixos>' 122 123nix-repl> config.<xref linkend="opt-networking.hostName"/> 124"mandark" 125 126nix-repl> map (x: x.hostName) config.<xref linkend="opt-services.httpd.virtualHosts"/> 127[ "example.org" "example.gov" ] 128</screen> 129 </para> 130</section>