diff options
Diffstat (limited to 'nixos/doc/manual/configuration.xml')
-rw-r--r-- | nixos/doc/manual/configuration.xml | 1550 |
1 files changed, 0 insertions, 1550 deletions
diff --git a/nixos/doc/manual/configuration.xml b/nixos/doc/manual/configuration.xml deleted file mode 100644 index 6db2f117e750..000000000000 --- a/nixos/doc/manual/configuration.xml +++ /dev/null @@ -1,1550 +0,0 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xml:id="ch-configuration"> - -<title>Configuring NixOS</title> - -<para>This chapter describes how to configure various aspects of a -NixOS machine through the configuration file -<filename>/etc/nixos/configuration.nix</filename>. As described in -<xref linkend="sec-changing-config" />, changes to this file only take -effect after you run <command>nixos-rebuild</command>.</para> - - -<!--===============================================================--> - -<section xml:id="sec-configuration-syntax"><title>Configuration syntax</title> - -<section><title>The basics</title> - -<para>The NixOS configuration file -<filename>/etc/nixos/configuration.nix</filename> is actually a -<emphasis>Nix expression</emphasis>, which is the Nix package -manager’s purely functional language for describing how to build -packages and configurations. This means you have all the expressive -power of that language at your disposal, including the ability to -abstract over common patterns, which is very useful when managing -complex systems. The syntax and semantics of the Nix language are -fully described in the <link -xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix -manual</link>, but here we give a short overview of the most important -constructs useful in NixOS configuration files.</para> - -<para>The NixOS configuration file generally looks like this: - -<programlisting> -{ config, pkgs, ... }: - -{ <replaceable>option definitions</replaceable> -} -</programlisting> - -The first line (<literal>{ config, pkgs, ... }:</literal>) denotes -that this is actually a function that takes at least the two arguments - <varname>config</varname> and <varname>pkgs</varname>. (These are -explained later.) The function returns a <emphasis>set</emphasis> of -option definitions (<literal>{ <replaceable>...</replaceable> }</literal>). These definitions have the -form <literal><replaceable>name</replaceable> = -<replaceable>value</replaceable></literal>, where -<replaceable>name</replaceable> is the name of an option and -<replaceable>value</replaceable> is its value. For example, - -<programlisting> -{ config, pkgs, ... }: - -{ services.httpd.enable = true; - services.httpd.adminAddr = "alice@example.org"; - services.httpd.documentRoot = "/webroot"; -} -</programlisting> - -defines a configuration with three option definitions that together -enable the Apache HTTP Server with <filename>/webroot</filename> as -the document root.</para> - -<para>Sets can be nested, and in fact dots in option names are -shorthand for defining a set containing another set. For instance, -<option>services.httpd.enable</option> defines a set named -<varname>services</varname> that contains a set named -<varname>httpd</varname>, which in turn contains an option definition -named <varname>enable</varname> with value <literal>true</literal>. -This means that the example above can also be written as: - -<programlisting> -{ config, pkgs, ... }: - -{ services = { - httpd = { - enable = true; - adminAddr = "alice@example.org"; - documentRoot = "/webroot"; - }; - }; -} -</programlisting> - -which may be more convenient if you have lots of option definitions -that share the same prefix (such as -<literal>services.httpd</literal>).</para> - -<para>NixOS checks your option definitions for correctness. For -instance, if you try to define an option that doesn’t exist (that is, -doesn’t have a corresponding <emphasis>option declaration</emphasis>), -<command>nixos-rebuild</command> will give an error like: -<screen> -The option `services.httpd.enabl' defined in `/etc/nixos/configuration.nix' does not exist. -</screen> -Likewise, values in option definitions must have a correct type. For -instance, <option>services.httpd.enable</option> must be a Boolean -(<literal>true</literal> or <literal>false</literal>). Trying to give -it a value of another type, such as a string, will cause an error: -<screen> -The option value `services.httpd.enable' in `/etc/nixos/configuration.nix' is not a boolean. -</screen> - -</para> - -<para>Options have various types of values. The most important are: - -<variablelist> - <varlistentry> - <term>Strings</term> - <listitem> - <para>Strings are enclosed in double quotes, e.g. - -<programlisting> -networking.hostName = "dexter"; -</programlisting> - - Special characters can be escaped by prefixing them with a - backslash (e.g. <literal>\"</literal>).</para> - - <para>Multi-line strings can be enclosed in <emphasis>double - single quotes</emphasis>, e.g. - -<programlisting> -networking.extraHosts = - '' - 127.0.0.2 other-localhost - 10.0.0.1 server - ''; -</programlisting> - - The main difference is that preceding whitespace is - automatically stripped from each line, and that characters like - <literal>"</literal> and <literal>\</literal> are not special - (making it more convenient for including things like shell - code).</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Booleans</term> - <listitem> - <para>These can be <literal>true</literal> or - <literal>false</literal>, e.g. - -<programlisting> -networking.firewall.enable = true; -networking.firewall.allowPing = false; -</programlisting> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Integers</term> - <listitem> - <para>For example, - -<programlisting> -boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 60; -</programlisting> - - (Note that here the attribute name - <literal>net.ipv4.tcp_keepalive_time</literal> is enclosed in - quotes to prevent it from being interpreted as a set named - <literal>net</literal> containing a set named - <literal>ipv4</literal>, and so on. This is because it’s not a - NixOS option but the literal name of a Linux kernel - setting.)</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Sets</term> - <listitem> - <para>Sets were introduced above. They are name/value pairs - enclosed in braces, as in the option definition - -<programlisting> -fileSystems."/boot" = - { device = "/dev/sda1"; - fsType = "ext4"; - options = "rw,data=ordered,relatime"; - }; -</programlisting> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Lists</term> - <listitem> - <para>The important thing to note about lists is that list - elements are separated by whitespace, like this: - -<programlisting> -boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ]; -</programlisting> - - List elements can be any other type, e.g. sets: - -<programlisting> -swapDevices = [ { device = "/dev/disk/by-label/swap"; } ]; -</programlisting> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>Packages</term> - <listitem> - <para>Usually, the packages you need are already part of the Nix - Packages collection, which is a set that can be accessed through - the function argument <varname>pkgs</varname>. Typical uses: - -<programlisting> -environment.systemPackages = - [ pkgs.thunderbird - pkgs.emacs - ]; - -postgresql.package = pkgs.postgresql90; -</programlisting> - - The latter option definition changes the default PostgreSQL - package used by NixOS’s PostgreSQL service to 9.0. For more - information on packages, including how to add new ones, see - <xref linkend="sec-custom-packages"/>.</para> - </listitem> - </varlistentry> - -</variablelist> - -</para> - -</section> - - -<section xml:id="sec-module-abstractions"><title>Abstractions</title> - -<para>If you find yourself repeating yourself over and over, it’s time -to abstract. Take, for instance, this Apache HTTP Server configuration: - -<programlisting> -{ - services.httpd.virtualHosts = - [ { hostName = "example.org"; - documentRoot = "/webroot"; - adminAddr = "alice@example.org"; - enableUserDir = true; - } - { hostName = "example.org"; - documentRoot = "/webroot"; - adminAddr = "alice@example.org"; - enableUserDir = true; - enableSSL = true; - sslServerCert = "/root/ssl-example-org.crt"; - sslServerKey = "/root/ssl-example-org.key"; - } - ]; -} -</programlisting> - -It defines two virtual hosts with nearly identical configuration; the -only difference is that the second one has SSL enabled. To prevent -this duplication, we can use a <literal>let</literal>: - -<programlisting> -let - exampleOrgCommon = - { hostName = "example.org"; - documentRoot = "/webroot"; - adminAddr = "alice@example.org"; - enableUserDir = true; - }; -in -{ - services.httpd.virtualHosts = - [ exampleOrgCommon - (exampleOrgCommon // { - enableSSL = true; - sslServerCert = "/root/ssl-example-org.crt"; - sslServerKey = "/root/ssl-example-org.key"; - }) - ]; -} -</programlisting> - -The <literal>let exampleOrgCommon = -<replaceable>...</replaceable></literal> defines a variable named -<literal>exampleOrgCommon</literal>. The <literal>//</literal> -operator merges two attribute sets, so the configuration of the second -virtual host is the set <literal>exampleOrgCommon</literal> extended -with the SSL options.</para> - -<para>You can write a <literal>let</literal> wherever an expression is -allowed. Thus, you also could have written: - -<programlisting> -{ - services.httpd.virtualHosts = - let exampleOrgCommon = <replaceable>...</replaceable>; in - [ exampleOrgCommon - (exampleOrgCommon // { <replaceable>...</replaceable> }) - ]; -} -</programlisting> - -but not <literal>{ let exampleOrgCommon = -<replaceable>...</replaceable>; in <replaceable>...</replaceable>; -}</literal> since attributes (as opposed to attribute values) are not -expressions.</para> - -<para><emphasis>Functions</emphasis> provide another method of -abstraction. For instance, suppose that we want to generate lots of -different virtual hosts, all with identical configuration except for -the host name. This can be done as follows: - -<programlisting> -{ - services.httpd.virtualHosts = - let - makeVirtualHost = name: - { hostName = name; - documentRoot = "/webroot"; - adminAddr = "alice@example.org"; - }; - in - [ (makeVirtualHost "example.org") - (makeVirtualHost "example.com") - (makeVirtualHost "example.gov") - (makeVirtualHost "example.nl") - ]; -} -</programlisting> - -Here, <varname>makeVirtualHost</varname> is a function that takes a -single argument <literal>name</literal> and returns the configuration -for a virtual host. That function is then called for several names to -produce the list of virtual host configurations.</para> - -<para>We can further improve on this by using the function -<varname>map</varname>, which applies another function to every -element in a list: - -<programlisting> -{ - services.httpd.virtualHosts = - let - makeVirtualHost = <replaceable>...</replaceable>; - in map makeVirtualHost - [ "example.org" "example.com" "example.gov" "example.nl" ]; -} -</programlisting> - -(The function <literal>map</literal> is called a -<emphasis>higher-order function</emphasis> because it takes another -function as an argument.)</para> - -<para>What if you need more than one argument, for instance, if we -want to use a different <literal>documentRoot</literal> for each -virtual host? Then we can make <varname>makeVirtualHost</varname> a -function that takes a <emphasis>set</emphasis> as its argument, like this: - -<programlisting> -{ - services.httpd.virtualHosts = - let - makeVirtualHost = { name, root }: - { hostName = name; - documentRoot = root; - adminAddr = "alice@example.org"; - }; - in map makeVirtualHost - [ { name = "example.org"; root = "/sites/example.org"; } - { name = "example.com"; root = "/sites/example.com"; } - { name = "example.gov"; root = "/sites/example.gov"; } - { name = "example.nl"; root = "/sites/example.nl"; } - ]; -} -</programlisting> - -But in this case (where every root is a subdirectory of -<filename>/sites</filename> named after the virtual host), it would -have been shorter to define <varname>makeVirtualHost</varname> as -<programlisting> -makeVirtualHost = name: - { hostName = name; - documentRoot = "/sites/${name}"; - adminAddr = "alice@example.org"; - }; -</programlisting> - -Here, the construct -<literal>${<replaceable>...</replaceable>}</literal> allows the result -of an expression to be spliced into a string.</para> - -</section> - - -<section xml:id="sec-modularity"><title>Modularity</title> - -<para>The NixOS configuration mechanism is modular. If your -<filename>configuration.nix</filename> becomes too big, you can split -it into multiple files. Likewise, if you have multiple NixOS -configurations (e.g. for different computers) with some commonality, -you can move the common configuration into a shared file.</para> - -<para>Modules have exactly the same syntax as -<filename>configuration.nix</filename>. In fact, -<filename>configuration.nix</filename> is itself a module. You can -use other modules by including them from -<filename>configuration.nix</filename>, e.g.: - -<programlisting> -{ config, pkgs, ... }: - -{ imports = [ ./vpn.nix ./kde.nix ]; - services.httpd.enable = true; - environment.systemPackages = [ pkgs.emacs ]; - <replaceable>...</replaceable> -} -</programlisting> - -Here, we include two modules from the same directory, -<filename>vpn.nix</filename> and <filename>kde.nix</filename>. The -latter might look like this: - -<programlisting> -{ config, pkgs, ... }: - -{ services.xserver.enable = true; - services.xserver.displayManager.kdm.enable = true; - services.xserver.desktopManager.kde4.enable = true; - environment.systemPackages = [ pkgs.kde4.kscreensaver ]; -} -</programlisting> - -Note that both <filename>configuration.nix</filename> and -<filename>kde.nix</filename> define the option -<option>environment.systemPackages</option>. When multiple modules -define an option, NixOS will try to <emphasis>merge</emphasis> the -definitions. In the case of -<option>environment.systemPackages</option>, that’s easy: the lists of -packages can simply be concatenated. The value in -<filename>configuration.nix</filename> is merged last, so for -list-type options, it will appear at the end of the merged list. If -you want it to appear first, you can use <varname>mkBefore</varname>: - -<programlisting> -boot.kernelModules = mkBefore [ "kvm-intel" ]; -</programlisting> - -This causes the <literal>kvm-intel</literal> kernel module to be -loaded before any other kernel modules.</para> - -<para>For other types of options, a merge may not be possible. For -instance, if two modules define -<option>services.httpd.adminAddr</option>, -<command>nixos-rebuild</command> will give an error: - -<screen> -The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. -</screen> - -When that happens, it’s possible to force one definition take -precedence over the others: - -<programlisting> -services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org"; -</programlisting> - -</para> - -<para>When using multiple modules, you may need to access -configuration values defined in other modules. This is what the -<varname>config</varname> function argument is for: it contains the -complete, merged system configuration. That is, -<varname>config</varname> is the result of combining the -configurations returned by every module<footnote><para>If you’re -wondering how it’s possible that the (indirect) -<emphasis>result</emphasis> of a function is passed as an -<emphasis>input</emphasis> to that same function: that’s because Nix -is a “lazy” language — it only computes values when they are needed. -This works as long as no individual configuration value depends on -itself.</para></footnote>. For example, here is a module that adds -some packages to <option>environment.systemPackages</option> only if -<option>services.xserver.enable</option> is set to -<literal>true</literal> somewhere else: - -<programlisting> -{ config, pkgs, ... }: - -{ environment.systemPackages = - if config.services.xserver.enable then - [ pkgs.firefox - pkgs.thunderbird - ] - else - [ ]; -} -</programlisting> - -</para> - -<para>With multiple modules, it may not be obvious what the final -value of a configuration option is. The command -<option>nixos-option</option> allows you to find out: - -<screen> -$ nixos-option services.xserver.enable -true - -$ nixos-option boot.kernelModules -[ "tun" "ipv6" "loop" <replaceable>...</replaceable> ] -</screen> - -Interactive exploration of the configuration is possible using -<command -xlink:href="https://github.com/edolstra/nix-repl">nix-repl</command>, -a read-eval-print loop for Nix expressions. It’s not installed by -default; run <literal>nix-env -i nix-repl</literal> to get it. A -typical use: - -<screen> -$ nix-repl '<nixos>' - -nix-repl> config.networking.hostName -"mandark" - -nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts -[ "example.org" "example.gov" ] -</screen> - -</para> - -</section> - - -<section xml:id="sec-nix-syntax-summary"><title>Syntax summary</title> - -<para>Below is a summary of the most important syntactic constructs in -the Nix expression language. It’s not complete. In particular, there -are many other built-in functions. See the <link -xlink:href="http://nixos.org/nix/manual/#chap-writing-nix-expressions">Nix -manual</link> for the rest.</para> - -<informaltable frame='none'> - <tgroup cols='2'> - <colspec colname='c1' rowsep='1' colsep='1' /> - <colspec colname='c2' rowsep='1' /> - <thead> - <row> - <entry>Example</entry> - <entry>Description</entry> - </row> - </thead> - <tbody> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Basic values</emphasis></entry> - </row> - <row> - <entry><literal>"Hello world"</literal></entry> - <entry>A string</entry> - </row> - <row> - <entry><literal>"${pkgs.bash}/bin/sh"</literal></entry> - <entry>A string containing an expression (expands to <literal>"/nix/store/<replaceable>hash</replaceable>-bash-<replaceable>version</replaceable>/bin/sh"</literal>)</entry> - </row> - <row> - <entry><literal>true</literal>, <literal>false</literal></entry> - <entry>Booleans</entry> - </row> - <row> - <entry><literal>123</literal></entry> - <entry>An integer</entry> - </row> - <row> - <entry><literal>./foo.png</literal></entry> - <entry>A path (relative to the containing Nix expression)</entry> - </row> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Compound values</emphasis></entry> - </row> - <row> - <entry><literal>{ x = 1; y = 2; }</literal></entry> - <entry>An set with attributes names <literal>x</literal> and <literal>y</literal></entry> - </row> - <row> - <entry><literal>{ foo.bar = 1; }</literal></entry> - <entry>A nested set, equivalent to <literal>{ foo = { bar = 1; }; }</literal></entry> - </row> - <row> - <entry><literal>rec { x = "bla"; y = x + "bar"; }</literal></entry> - <entry>A recursive set, equivalent to <literal>{ x = "foo"; y = "foobar"; }</literal></entry> - </row> - <row> - <entry><literal>[ "foo" "bar" ]</literal></entry> - <entry>A list with two elements</entry> - </row> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Operators</emphasis></entry> - </row> - <row> - <entry><literal>"foo" + "bar"</literal></entry> - <entry>String concatenation</entry> - </row> - <row> - <entry><literal>1 + 2</literal></entry> - <entry>Integer addition</entry> - </row> - <row> - <entry><literal>"foo" == "f" + "oo"</literal></entry> - <entry>Equality test (evaluates to <literal>true</literal>)</entry> - </row> - <row> - <entry><literal>"foo" != "bar"</literal></entry> - <entry>Inequality test (evaluates to <literal>true</literal>)</entry> - </row> - <row> - <entry><literal>!true</literal></entry> - <entry>Boolean negation</entry> - </row> - <row> - <entry><literal>{ x = 1; y = 2; }.x</literal></entry> - <entry>Attribute selection (evaluates to <literal>1</literal>)</entry> - </row> - <row> - <entry><literal>{ x = 1; y = 2; }.z or 3</literal></entry> - <entry>Attribute selection with default (evaluates to <literal>3</literal>)</entry> - </row> - <row> - <entry><literal>{ x = 1; y = 2; } // { z = 3; }</literal></entry> - <entry>Merge two sets (attributes in the right-hand set taking precedence)</entry> - </row> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Control structures</emphasis></entry> - </row> - <row> - <entry><literal>if 1 + 1 == 2 then "yes!" else "no!"</literal></entry> - <entry>Conditional expression</entry> - </row> - <row> - <entry><literal>assert 1 + 1 == 2; "yes!"</literal></entry> - <entry>Assertion check (evaluates to <literal>"yes!"</literal>)</entry> - </row> - <row> - <entry><literal>let x = "foo"; y = "bar"; in x + y</literal></entry> - <entry>Variable definition</entry> - </row> - <row> - <entry><literal>with pkgs.lib; head [ 1 2 3 ]</literal></entry> - <entry>Add all attributes from the given set to the scope - (evaluates to <literal>1</literal>)</entry> - </row> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Functions (lambdas)</emphasis></entry> - </row> - <row> - <entry><literal>x: x + 1</literal></entry> - <entry>A function that expects an integer and returns it increased by 1</entry> - </row> - <row> - <entry><literal>(x: x + 1) 100</literal></entry> - <entry>A function call (evaluates to 101)</entry> - </row> - <row> - <entry><literal>let inc = x: x + 1; in inc (inc (inc 100))</literal></entry> - <entry>A function bound to a variable and subsequently called by name (evaluates to 103)</entry> - </row> - <row> - <entry><literal>{ x, y }: x + y</literal></entry> - <entry>A function that expects a set with required attributes - <literal>x</literal> and <literal>y</literal> and concatenates - them</entry> - </row> - <row> - <entry><literal>{ x, y ? "bar" }: x + y</literal></entry> - <entry>A function that expects a set with required attribute - <literal>x</literal> and optional <literal>y</literal>, using - <literal>"bar"</literal> as default value for - <literal>y</literal></entry> - </row> - <row> - <entry><literal>{ x, y, ... }: x + y</literal></entry> - <entry>A function that expects a set with required attributes - <literal>x</literal> and <literal>y</literal> and ignores any - other attributes</entry> - </row> - <row> - <entry><literal>{ x, y } @ args: x + y</literal></entry> - <entry>A function that expects a set with required attributes - <literal>x</literal> and <literal>y</literal>, and binds the - whole set to <literal>args</literal></entry> - </row> - - <row> - <entry namest="c1" nameend="c2"><emphasis>Built-in functions</emphasis></entry> - </row> - <row> - <entry><literal>import ./foo.nix</literal></entry> - <entry>Load and return Nix expression in given file</entry> - </row> - <row> - <entry><literal>map (x: x + x) [ 1 2 3 ]</literal></entry> - <entry>Apply a function to every element of a list (evaluates to <literal>[ 2 4 6 ]</literal>)</entry> - </row> - <!-- - <row> - <entry><literal>throw "Urgh"</literal></entry> - <entry>Raise an error condition</entry> - </row> - --> - - </tbody> - </tgroup> -</informaltable> - -</section> - - -</section> - - -<!--===============================================================--> - -<section xml:id="sec-package-management"><title>Package management</title> - -<para>This section describes how to add additional packages to your -system. NixOS has two distinct styles of package management: - -<itemizedlist> - - <listitem><para><emphasis>Declarative</emphasis>, where you declare - what packages you want in your - <filename>configuration.nix</filename>. Every time you run - <command>nixos-rebuild</command>, NixOS will ensure that you get a - consistent set of binaries corresponding to your - specification.</para></listitem> - - <listitem><para><emphasis>Ad hoc</emphasis>, where you install, - upgrade and uninstall packages via the <command>nix-env</command> - command. This style allows mixing packages from different Nixpkgs - versions. It’s the only choice for non-root - users.</para></listitem> - -</itemizedlist> - -</para> - -<para>The next two sections describe these two styles.</para> - - -<section><title>Declarative package management</title> - -<para>With declarative package management, you specify which packages -you want on your system by setting the option -<option>environment.systemPackages</option>. For instance, adding the -following line to <filename>configuration.nix</filename> enables the -Mozilla Thunderbird email application: - -<programlisting> -environment.systemPackages = [ pkgs.thunderbird ]; -</programlisting> - -The effect of this specification is that the Thunderbird package from -Nixpkgs will be built or downloaded as part of the system when you run -<command>nixos-rebuild switch</command>.</para> - -<para>You can get a list of the available packages as follows: -<screen> -$ nix-env -qaP '*' --description -nixos.pkgs.firefox firefox-23.0 Mozilla Firefox - the browser, reloaded -<replaceable>...</replaceable> -</screen> - -The first column in the output is the <emphasis>attribute -name</emphasis>, such as -<literal>nixos.pkgs.thunderbird</literal>. (The -<literal>nixos</literal> prefix allows distinguishing between -different channels that you might have.)</para> - -<para>To “uninstall” a package, simply remove it from -<option>environment.systemPackages</option> and run -<command>nixos-rebuild switch</command>.</para> - - -<section xml:id="sec-customising-packages"><title>Customising packages</title> - -<para>Some packages in Nixpkgs have options to enable or disable -optional functionality or change other aspects of the package. For -instance, the Firefox wrapper package (which provides Firefox with a -set of plugins such as the Adobe Flash player) has an option to enable -the Google Talk plugin. It can be set in -<filename>configuration.nix</filename> as follows: - -<filename> -nixpkgs.config.firefox.enableGoogleTalkPlugin = true; -</filename> -</para> - -<warning><para>Unfortunately, Nixpkgs currently lacks a way to query -available configuration options.</para></warning> - -<para>Apart from high-level options, it’s possible to tweak a package -in almost arbitrary ways, such as changing or disabling dependencies -of a package. For instance, the Emacs package in Nixpkgs by default -has a dependency on GTK+ 2. If you want to build it against GTK+ 3, -you can specify that as follows: - -<programlisting> -environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ]; -</programlisting> - -The function <varname>override</varname> performs the call to the Nix -function that produces Emacs, with the original arguments amended by -the set of arguments specified by you. So here the function argument -<varname>gtk</varname> gets the value <literal>pkgs.gtk3</literal>, -causing Emacs to depend on GTK+ 3. (The parentheses are necessary -because in Nix, function application binds more weakly than list -construction, so without them, -<literal>environment.systemPackages</literal> would be a list with two -elements.)</para> - -<para>Even greater customisation is possible using the function -<varname>overrideDerivation</varname>. While the -<varname>override</varname> mechanism above overrides the arguments of -a package function, <varname>overrideDerivation</varname> allows -changing the <emphasis>result</emphasis> of the function. This -permits changing any aspect of the package, such as the source code. -For instance, if you want to override the source code of Emacs, you -can say: - -<programlisting> -environment.systemPackages = - [ (pkgs.lib.overrideDerivation pkgs.emacs (attrs: { - name = "emacs-25.0-pre"; - src = /path/to/my/emacs/tree; - })) - ]; -</programlisting> - -Here, <varname>overrideDerivation</varname> takes the Nix derivation -specified by <varname>pkgs.emacs</varname> and produces a new -derivation in which the original’s <literal>name</literal> and -<literal>src</literal> attribute have been replaced by the given -values. The original attributes are accessible via -<varname>attrs</varname>.</para> - -<para>The overrides shown above are not global. They do not affect -the original package; other packages in Nixpkgs continue to depend on -the original rather than the customised package. This means that if -another package in your system depends on the original package, you -end up with two instances of the package. If you want to have -everything depend on your customised instance, you can apply a -<emphasis>global</emphasis> override as follows: - -<screen> -nixpkgs.config.packageOverrides = pkgs: - { emacs = pkgs.emacs.override { gtk = pkgs.gtk3; }; - }; -</screen> - -The effect of this definition is essentially equivalent to modifying -the <literal>emacs</literal> attribute in the Nixpkgs source tree. -Any package in Nixpkgs that depends on <literal>emacs</literal> will -be passed your customised instance. (However, the value -<literal>pkgs.emacs</literal> in -<varname>nixpkgs.config.packageOverrides</varname> refers to the -original rather than overridden instance, to prevent an infinite -recursion.)</para> - -</section> - -<section xml:id="sec-custom-packages"><title>Adding custom packages</title> - -<para>It’s possible that a package you need is not available in NixOS. -In that case, you can do two things. First, you can clone the Nixpkgs -repository, add the package to your clone, and (optionally) submit a -patch or pull request to have it accepted into the main Nixpkgs -repository. This is described in detail in the <link -xlink:href="http://nixos.org/nixpkgs/manual">Nixpkgs manual</link>. -In short, you clone Nixpkgs: - -<screen> -$ git clone git://github.com/NixOS/nixpkgs.git -$ cd nixpkgs -</screen> - -Then you write and test the package as described in the Nixpkgs -manual. Finally, you add it to -<literal>environment.systemPackages</literal>, e.g. - -<programlisting> -environment.systemPackages = [ pkgs.my-package ]; -</programlisting> - -and you run <command>nixos-rebuild</command>, specifying your own -Nixpkgs tree: - -<screen> -$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen> - -</para> - -<para>The second possibility is to add the package outside of the -Nixpkgs tree. For instance, here is how you specify a build of the -<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link> -package directly in <filename>configuration.nix</filename>: - -<programlisting> -environment.systemPackages = - let - my-hello = with pkgs; stdenv.mkDerivation rec { - name = "hello-2.8"; - src = fetchurl { - url = "mirror://gnu/hello/${name}.tar.gz"; - sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6"; - }; - }; - in - [ my-hello ]; -</programlisting> - -Of course, you can also move the definition of -<literal>my-hello</literal> into a separate Nix expression, e.g. -<programlisting> -environment.systemPackages = [ (import ./my-hello.nix) ]; -</programlisting> -where <filename>my-hello.nix</filename> contains: -<programlisting> -with import <nixpkgs> {}; # bring all of Nixpkgs into scope - -stdenv.mkDerivation rec { - name = "hello-2.8"; - src = fetchurl { - url = "mirror://gnu/hello/${name}.tar.gz"; - sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6"; - }; -} -</programlisting> - -This allows testing the package easily: -<screen> -$ nix-build my-hello.nix -$ ./result/bin/hello -Hello, world! -</screen> - -</para> - -</section> - -</section> - - -<section><title>Ad hoc package management</title> - -<para>With the command <command>nix-env</command>, you can install and -uninstall packages from the command line. For instance, to install -Mozilla Thunderbird: - -<screen> -$ nix-env -iA nixos.pkgs.thunderbird</screen> - -If you invoke this as root, the package is installed in the Nix -profile <filename>/nix/var/nix/profiles/default</filename> and visible -to all users of the system; otherwise, the package ends up in -<filename>/nix/var/nix/profiles/per-user/<replaceable>username</replaceable>/profile</filename> -and is not visible to other users. The <option>-A</option> flag -specifies the package by its attribute name; without it, the package -is installed by matching against its package name -(e.g. <literal>thunderbird</literal>). The latter is slower because -it requires matching against all available Nix packages, and is -ambiguous if there are multiple matching packages.</para> - -<para>Packages come from the NixOS channel. You typically upgrade a -package by updating to the latest version of the NixOS channel: -<screen> -$ nix-channel --update nixos -</screen> -and then running <literal>nix-env -i</literal> again. Other packages -in the profile are <emphasis>not</emphasis> affected; this is the -crucial difference with the declarative style of package management, -where running <command>nixos-rebuild switch</command> causes all -packages to be updated to their current versions in the NixOS channel. -You can however upgrade all packages for which there is a newer -version by doing: -<screen> -$ nix-env -u '*' -</screen> -</para> - -<para>A package can be uninstalled using the <option>-e</option> -flag: -<screen> -$ nix-env -e thunderbird -</screen> -</para> - -<para>Finally, you can roll back an undesirable -<command>nix-env</command> action: -<screen> -$ nix-env --rollback -</screen> -</para> - -<para><command>nix-env</command> has many more flags. For details, -see the -<citerefentry><refentrytitle>nix-env</refentrytitle><manvolnum>1</manvolnum></citerefentry> -manpage or the Nix manual.</para> - -</section> - - -</section> - - -<!--===============================================================--> - -<section xml:id="sec-user-management"><title>User management</title> - -<para>NixOS supports both declarative and imperative styles of user -management. In the declarative style, users are specified in -<filename>configuration.nix</filename>. For instance, the following -states that a user account named <literal>alice</literal> shall exist: - -<programlisting> -users.extraUsers.alice = - { isNormalUser = true; - description = "Alice Foobar"; - extraGroups = [ "wheel" "networkmanager" ]; - openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ]; - }; -</programlisting> - -Note that <literal>alice</literal> is a member of the -<literal>wheel</literal> and <literal>networkmanager</literal> groups, -which allows her to use <command>sudo</command> to execute commands as -<literal>root</literal> and to configure the network, respectively. -Also note the SSH public key that allows remote logins with the -corresponding private key. Users created in this way do not have a -password by default, so they cannot log in via mechanisms that require -a password. However, you can use the <command>passwd</command> program -to set a password, which is retained across invocations of -<command>nixos-rebuild</command>.</para> - -<para>A user ID (uid) is assigned automatically. You can also specify -a uid manually by adding - -<programlisting> - uid = 1000; -</programlisting> - -to the user specification.</para> - -<para>Groups can be specified similarly. The following states that a -group named <literal>students</literal> shall exist: - -<programlisting> -users.extraGroups.students.gid = 1000; -</programlisting> - -As with users, the group ID (gid) is optional and will be assigned -automatically if it’s missing.</para> - -<para>In the imperative style, users and groups are managed by -commands such as <command>useradd</command>, -<command>groupmod</command> and so on. For instance, to create a user -account named <literal>alice</literal>: - -<screen> -$ useradd -m alice</screen> - -The flag <option>-m</option> causes the creation of a home directory -for the new user, which is generally what you want. The user does not -have an initial password and therefore cannot log in. A password can -be set using the <command>passwd</command> utility: - -<screen> -$ passwd alice -Enter new UNIX password: *** -Retype new UNIX password: *** -</screen> - -A user can be deleted using <command>userdel</command>: - -<screen> -$ userdel -r alice</screen> - -The flag <option>-r</option> deletes the user’s home directory. -Accounts can be modified using <command>usermod</command>. Unix -groups can be managed using <command>groupadd</command>, -<command>groupmod</command> and <command>groupdel</command>.</para> - -</section> - - -<!--===============================================================--> - -<section><title>File systems</title> - -<para>You can define file systems using the -<option>fileSystems</option> configuration option. For instance, the -following definition causes NixOS to mount the Ext4 file system on -device <filename>/dev/disk/by-label/data</filename> onto the mount -point <filename>/data</filename>: - -<programlisting> -fileSystems."/data" = - { device = "/dev/disk/by-label/data"; - fsType = "ext4"; - }; -</programlisting> - -Mount points are created automatically if they don’t already exist. -For <option>device</option>, it’s best to use the topology-independent -device aliases in <filename>/dev/disk/by-label</filename> and -<filename>/dev/disk/by-uuid</filename>, as these don’t change if the -topology changes (e.g. if a disk is moved to another IDE -controller).</para> - -<para>You can usually omit the file system type -(<option>fsType</option>), since <command>mount</command> can usually -detect the type and load the necessary kernel module automatically. -However, if the file system is needed at early boot (in the initial -ramdisk) and is not <literal>ext2</literal>, <literal>ext3</literal> -or <literal>ext4</literal>, then it’s best to specify -<option>fsType</option> to ensure that the kernel module is -available.</para> - -<section><title>LUKS-encrypted file systems</title> - -<para>NixOS supports file systems that are encrypted using -<emphasis>LUKS</emphasis> (Linux Unified Key Setup). For example, -here is how you create an encrypted Ext4 file system on the device -<filename>/dev/sda2</filename>: - -<screen> -$ cryptsetup luksFormat /dev/sda2 - -WARNING! -======== -This will overwrite data on /dev/sda2 irrevocably. - -Are you sure? (Type uppercase yes): YES -Enter LUKS passphrase: *** -Verify passphrase: *** - -$ cryptsetup luksOpen /dev/sda2 crypted -Enter passphrase for /dev/sda2: *** - -$ mkfs.ext4 /dev/mapper/crypted -</screen> - -To ensure that this file system is automatically mounted at boot time -as <filename>/</filename>, add the following to -<filename>configuration.nix</filename>: - -<programlisting> -boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ]; -fileSystems."/".device = "/dev/mapper/crypted"; -</programlisting> - -</para> - -</section> - -</section> - - -<!--===============================================================--> - -<section xml:id="sec-x11"><title>X Window System</title> - -<para>The X Window System (X11) provides the basis of NixOS’ graphical -user interface. It can be enabled as follows: -<programlisting> -services.xserver.enable = true; -</programlisting> -The X server will automatically detect and use the appropriate video -driver from a set of X.org drivers (such as <literal>vesa</literal> -and <literal>intel</literal>). You can also specify a driver -manually, e.g. -<programlisting> -services.xserver.videoDrivers = [ "r128" ]; -</programlisting> -to enable X.org’s <literal>xf86-video-r128</literal> driver.</para> - -<para>You also need to enable at least one desktop or window manager. -Otherwise, you can only log into a plain undecorated -<command>xterm</command> window. Thus you should pick one or more of -the following lines: -<programlisting> -services.xserver.desktopManager.kde4.enable = true; -services.xserver.desktopManager.xfce.enable = true; -services.xserver.windowManager.xmonad.enable = true; -services.xserver.windowManager.twm.enable = true; -services.xserver.windowManager.icewm.enable = true; -</programlisting> -</para> - -<para>NixOS’s default <emphasis>display manager</emphasis> (the -program that provides a graphical login prompt and manages the X -server) is SLiM. You can select KDE’s <command>kdm</command> instead: -<programlisting> -services.xserver.displayManager.kdm.enable = true; -</programlisting> -</para> - -<para>The X server is started automatically at boot time. If you -don’t want this to happen, you can set: -<programlisting> -services.xserver.autorun = false; -</programlisting> -The X server can then be started manually: -<screen> -$ systemctl start display-manager.service -</screen> -</para> - - -<section><title>NVIDIA graphics cards</title> - -<para>NVIDIA provides a proprietary driver for its graphics cards that -has better 3D performance than the X.org drivers. It is not enabled -by default because it’s not free software. You can enable it as follows: -<programlisting> -services.xserver.videoDrivers = [ "nvidia" ]; -</programlisting> -You may need to reboot after enabling this driver to prevent a clash -with other kernel modules.</para> - -<para>On 64-bit systems, if you want full acceleration for 32-bit -programs such as Wine, you should also set the following: -<programlisting> -services.xserver.driSupport32Bit = true; -</programlisting> -</para> - -</section> - - -<section><title>Touchpads</title> - -<para>Support for Synaptics touchpads (found in many laptops such as -the Dell Latitude series) can be enabled as follows: -<programlisting> -services.xserver.synaptics.enable = true; -</programlisting> -The driver has many options (see <xref linkend="ch-options"/>). For -instance, the following enables two-finger scrolling: -<programlisting> -services.xserver.synaptics.twoFingerScroll = true; -</programlisting> -</para> - -</section> - - -</section> - - -<!--===============================================================--> - -<section xml:id="sec-networking"><title>Networking</title> - -<section xml:id="sec-networkmanager"><title>NetworkManager</title> - -<para>To facilitate network configuration, some desktop environments -use NetworkManager. You can enable NetworkManager by setting: - -<programlisting> -services.networkmanager.enable = true; -</programlisting> - -Some desktop managers (e.g., GNOME) enable NetworkManager -automatically for you.</para> - -<para>All users that should have permission to change network settings -must belong to the <code>networkmanager</code> group.</para> - -<note><para><code>services.networkmanager</code> and -<code>services.wireless</code> can not be enabled at the same time: -you can still connect to the wireless networks using -NetworkManager.</para></note> - -</section> - -<section xml:id="sec-ssh"><title>Secure shell access</title> - -<para>Secure shell (SSH) access to your machine can be enabled by -setting: - -<programlisting> -services.openssh.enable = true; -</programlisting> - -By default, root logins using a password are disallowed. They can be -disabled entirely by setting -<literal>services.openssh.permitRootLogin</literal> to -<literal>"no"</literal>.</para> - -<para>You can declaratively specify authorised RSA/DSA public keys for -a user as follows: - -<!-- FIXME: this might not work if the user is unmanaged. --> -<programlisting> -users.extraUsers.alice.openssh.authorizedKeys.keys = - [ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ]; -</programlisting> - -</para> - -</section> - - -<section xml:id="sec-ipv4"><title>IPv4 configuration</title> - -<para>By default, NixOS uses DHCP (specifically, -<command>dhcpcd</command>) to automatically configure network -interfaces. However, you can configure an interface manually as -follows: - -<programlisting> -networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; }; -</programlisting> - -(The network prefix can also be specified using the option -<literal>subnetMask</literal>, -e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.) -Typically you’ll also want to set a default gateway and set of name -servers: - -<programlisting> -networking.defaultGateway = "192.168.1.1"; -networking.nameservers = [ "8.8.8.8" ]; -</programlisting> - -</para> - -<note><para>Statically configured interfaces are set up by the systemd -service -<replaceable>interface-name</replaceable><literal>-cfg.service</literal>. -The default gateway and name server configuration is performed by -<literal>network-setup.service</literal>.</para></note> - -<para>The host name is set using <option>networking.hostName</option>: - -<programlisting> -networking.hostName = "cartman"; -</programlisting> - -The default host name is <literal>nixos</literal>. Set it to the -empty string (<literal>""</literal>) to allow the DHCP server to -provide the host name.</para> - -</section> - - -<section xml:id="sec-ipv6"><title>IPv6 configuration</title> - -<para>IPv6 is enabled by default. Stateless address autoconfiguration -is used to automatically assign IPv6 addresses to all interfaces. You -can disable IPv6 support globally by setting: - -<programlisting> -networking.enableIPv6 = false; -</programlisting> - -</para> - -</section> - - -<section xml:id="sec-firewall"><title>Firewall</title> - -<para>NixOS has a simple stateful firewall that blocks incoming -connections and other unexpected packets. The firewall applies to -both IPv4 and IPv6 traffic. It is enabled by default. It can be -disabled as follows: - -<programlisting> -networking.firewall.enable = false; -</programlisting> - -If the firewall is enabled, you can open specific TCP ports to the -outside world: - -<programlisting> -networking.firewall.allowedTCPPorts = [ 80 443 ]; -</programlisting> - -Note that TCP port 22 (ssh) is opened automatically if the SSH daemon -is enabled (<option>services.openssh.enable = true</option>). UDP -ports can be opened through -<option>networking.firewall.allowedUDPPorts</option>. Also of -interest is - -<programlisting> -networking.firewall.allowPing = true; -</programlisting> - -to allow the machine to respond to ping requests. (ICMPv6 pings are -always allowed.)</para> - -</section> - - -<section xml:id="sec-wireless"><title>Wireless networks</title> - -<para>For a desktop installation using NetworkManager (e.g., GNOME), -you just have to make sure the user is in the -<code>networkmanager</code> group and you can skip the rest of this -section on wireless networks.</para> - -<para> -NixOS will start wpa_supplicant for you if you enable this setting: - -<programlisting> -networking.wireless.enable = true; -</programlisting> - -NixOS currently does not generate wpa_supplicant's -configuration file, <literal>/etc/wpa_supplicant.conf</literal>. You should edit this file -yourself to define wireless networks, WPA keys and so on (see -wpa_supplicant.conf(5)). -</para> - -<para> -If you are using WPA2 the <command>wpa_passphrase</command> tool might be useful -to generate the <literal>wpa_supplicant.conf</literal>. - -<screen> -$ wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen> - -After you have edited the <literal>wpa_supplicant.conf</literal>, -you need to restart the wpa_supplicant service. - -<screen> -$ systemctl restart wpa_supplicant.service</screen> -</para> - - -</section> - - -<section><title>Ad-hoc configuration</title> - -<para>You can use <option>networking.localCommands</option> to specify -shell commands to be run at the end of -<literal>network-setup.service</literal>. This is useful for doing -network configuration not covered by the existing NixOS modules. For -instance, to statically configure an IPv6 address: - -<programlisting> -networking.localCommands = - '' - ip -6 addr add 2001:610:685:1::1/64 dev eth0 - ''; -</programlisting> - -</para> - -</section> - - -<!-- TODO: OpenVPN, NAT --> - - -</section> - - -<!--===============================================================--> - -<section xml:id="sec-kernel-config"><title>Linux kernel</title> - -<para>You can override the Linux kernel and associated packages using -the option <option>boot.kernelPackages</option>. For instance, this -selects the Linux 3.10 kernel: -<programlisting> -boot.kernelPackages = pkgs.linuxPackages_3_10; -</programlisting> -Note that this not only replaces the kernel, but also packages that -are specific to the kernel version, such as the NVIDIA video drivers. -This ensures that driver packages are consistent with the -kernel.</para> - -<para>The default Linux kernel configuration should be fine for most users. You can see the configuration of your current kernel with the following command: -<programlisting> -cat /proc/config.gz | gunzip -</programlisting> -If you want to change the kernel configuration, you can use the -<option>packageOverrides</option> feature (see <xref -linkend="sec-customising-packages" />). For instance, to enable -support for the kernel debugger KGDB: - -<programlisting> -nixpkgs.config.packageOverrides = pkgs: - { linux_3_4 = pkgs.linux_3_4.override { - extraConfig = - '' - KGDB y - ''; - }; - }; -</programlisting> - -<varname>extraConfig</varname> takes a list of Linux kernel -configuration options, one per line. The name of the option should -not include the prefix <literal>CONFIG_</literal>. The option value -is typically <literal>y</literal>, <literal>n</literal> or -<literal>m</literal> (to build something as a kernel module).</para> - -<para>Kernel modules for hardware devices are generally loaded -automatically by <command>udev</command>. You can force a module to -be loaded via <option>boot.kernelModules</option>, e.g. -<programlisting> -boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ]; -</programlisting> -If the module is required early during the boot (e.g. to mount the -root file system), you can use -<option>boot.initrd.extraKernelModules</option>: -<programlisting> -boot.initrd.extraKernelModules = [ "cifs" ]; -</programlisting> -This causes the specified modules and their dependencies to be added -to the initial ramdark.</para> - -<para>Kernel runtime parameters can be set through -<option>boot.kernel.sysctl</option>, e.g. -<programlisting> -boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120; -</programlisting> -sets the kernel’s TCP keepalive time to 120 seconds. To see the -available parameters, run <command>sysctl -a</command>.</para> - -</section> - - -<!-- Apache; libvirtd virtualisation --> - - -</chapter> |