1<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-configuration-file">
2 <title>NixOS Configuration File</title>
3 <para>
4 The NixOS configuration file generally looks like this:
5 </para>
6 <programlisting language="bash">
7{ config, pkgs, ... }:
8
9{ option definitions
10}
11</programlisting>
12 <para>
13 The first line (<literal>{ config, pkgs, ... }:</literal>) denotes
14 that this is actually a function that takes at least the two
15 arguments <literal>config</literal> and <literal>pkgs</literal>.
16 (These are explained later, in chapter
17 <xref linkend="sec-writing-modules" />) The function returns a
18 <emphasis>set</emphasis> of option definitions
19 (<literal>{ ... }</literal>). These definitions have the form
20 <literal>name = value</literal>, where <literal>name</literal> is
21 the name of an option and <literal>value</literal> is its value. For
22 example,
23 </para>
24 <programlisting language="bash">
25{ config, pkgs, ... }:
26
27{ services.httpd.enable = true;
28 services.httpd.adminAddr = "alice@example.org";
29 services.httpd.virtualHosts.localhost.documentRoot = "/webroot";
30}
31</programlisting>
32 <para>
33 defines a configuration with three option definitions that together
34 enable the Apache HTTP Server with <literal>/webroot</literal> as
35 the document root.
36 </para>
37 <para>
38 Sets can be nested, and in fact dots in option names are shorthand
39 for defining a set containing another set. For instance,
40 <xref linkend="opt-services.httpd.enable" /> defines a set named
41 <literal>services</literal> that contains a set named
42 <literal>httpd</literal>, which in turn contains an option
43 definition named <literal>enable</literal> with value
44 <literal>true</literal>. This means that the example above can also
45 be written as:
46 </para>
47 <programlisting language="bash">
48{ config, pkgs, ... }:
49
50{ services = {
51 httpd = {
52 enable = true;
53 adminAddr = "alice@example.org";
54 virtualHosts = {
55 localhost = {
56 documentRoot = "/webroot";
57 };
58 };
59 };
60 };
61}
62</programlisting>
63 <para>
64 which may be more convenient if you have lots of option definitions
65 that share the same prefix (such as
66 <literal>services.httpd</literal>).
67 </para>
68 <para>
69 NixOS checks your option definitions for correctness. For instance,
70 if you try to define an option that doesn’t exist (that is, doesn’t
71 have a corresponding <emphasis>option declaration</emphasis>),
72 <literal>nixos-rebuild</literal> will give an error like:
73 </para>
74 <programlisting>
75The option `services.httpd.enable' defined in `/etc/nixos/configuration.nix' does not exist.
76</programlisting>
77 <para>
78 Likewise, values in option definitions must have a correct type. For
79 instance, <literal>services.httpd.enable</literal> must be a Boolean
80 (<literal>true</literal> or <literal>false</literal>). Trying to
81 give it a value of another type, such as a string, will cause an
82 error:
83 </para>
84 <programlisting>
85The option value `services.httpd.enable' in `/etc/nixos/configuration.nix' is not a boolean.
86</programlisting>
87 <para>
88 Options have various types of values. The most important are:
89 </para>
90 <variablelist>
91 <varlistentry>
92 <term>
93 Strings
94 </term>
95 <listitem>
96 <para>
97 Strings are enclosed in double quotes, e.g.
98 </para>
99 <programlisting language="bash">
100networking.hostName = "dexter";
101</programlisting>
102 <para>
103 Special characters can be escaped by prefixing them with a
104 backslash (e.g. <literal>\"</literal>).
105 </para>
106 <para>
107 Multi-line strings can be enclosed in <emphasis>double single
108 quotes</emphasis>, e.g.
109 </para>
110 <programlisting language="bash">
111networking.extraHosts =
112 ''
113 127.0.0.2 other-localhost
114 10.0.0.1 server
115 '';
116</programlisting>
117 <para>
118 The main difference is that it strips from each line a number
119 of spaces equal to the minimal indentation of the string as a
120 whole (disregarding the indentation of empty lines), and that
121 characters like <literal>"</literal> and
122 <literal>\</literal> are not special (making it more
123 convenient for including things like shell code). See more
124 info about this in the Nix manual
125 <link xlink:href="https://nixos.org/nix/manual/#ssec-values">here</link>.
126 </para>
127 </listitem>
128 </varlistentry>
129 <varlistentry>
130 <term>
131 Booleans
132 </term>
133 <listitem>
134 <para>
135 These can be <literal>true</literal> or
136 <literal>false</literal>, e.g.
137 </para>
138 <programlisting language="bash">
139networking.firewall.enable = true;
140networking.firewall.allowPing = false;
141</programlisting>
142 </listitem>
143 </varlistentry>
144 <varlistentry>
145 <term>
146 Integers
147 </term>
148 <listitem>
149 <para>
150 For example,
151 </para>
152 <programlisting language="bash">
153boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60;
154</programlisting>
155 <para>
156 (Note that here the attribute name
157 <literal>net.ipv4.tcp_keepalive_time</literal> is enclosed in
158 quotes to prevent it from being interpreted as a set named
159 <literal>net</literal> containing a set named
160 <literal>ipv4</literal>, and so on. This is because it’s not a
161 NixOS option but the literal name of a Linux kernel setting.)
162 </para>
163 </listitem>
164 </varlistentry>
165 <varlistentry>
166 <term>
167 Sets
168 </term>
169 <listitem>
170 <para>
171 Sets were introduced above. They are name/value pairs enclosed
172 in braces, as in the option definition
173 </para>
174 <programlisting language="bash">
175fileSystems."/boot" =
176 { device = "/dev/sda1";
177 fsType = "ext4";
178 options = [ "rw" "data=ordered" "relatime" ];
179 };
180</programlisting>
181 </listitem>
182 </varlistentry>
183 <varlistentry>
184 <term>
185 Lists
186 </term>
187 <listitem>
188 <para>
189 The important thing to note about lists is that list elements
190 are separated by whitespace, like this:
191 </para>
192 <programlisting language="bash">
193boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
194</programlisting>
195 <para>
196 List elements can be any other type, e.g. sets:
197 </para>
198 <programlisting language="bash">
199swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
200</programlisting>
201 </listitem>
202 </varlistentry>
203 <varlistentry>
204 <term>
205 Packages
206 </term>
207 <listitem>
208 <para>
209 Usually, the packages you need are already part of the Nix
210 Packages collection, which is a set that can be accessed
211 through the function argument <literal>pkgs</literal>. Typical
212 uses:
213 </para>
214 <programlisting language="bash">
215environment.systemPackages =
216 [ pkgs.thunderbird
217 pkgs.emacs
218 ];
219
220services.postgresql.package = pkgs.postgresql_14;
221</programlisting>
222 <para>
223 The latter option definition changes the default PostgreSQL
224 package used by NixOS’s PostgreSQL service to 10.x. For more
225 information on packages, including how to add new ones, see
226 <xref linkend="sec-custom-packages" />.
227 </para>
228 </listitem>
229 </varlistentry>
230 </variablelist>
231</section>