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