Overview of the NixOS Linux distribution: Difference between revisions

From NixOS Wiki
imported>HLandau
m change manual url
 
(65 intermediate revisions by 31 users not shown)
Line 1: Line 1:
{{Expansion|This article is incomplete.}}
{{Expansion|Incomplete (reason: it needs to be an easy introduction, because its one of the first articles new users read here. Thats why it needs to be simplified a bit and more complex topics should be moved to other articles))}}


[https://nixos.org/ NixOS] is a Linux distribution based on the [[Nix]] package manager and build system. It supports [https://en.wikipedia.org/wiki/Declarative_programming declarative] system-wide [https://en.wikipedia.org/wiki/Configuration_management configuration management] as well as [https://en.wikipedia.org/wiki/Atomicity_(database_systems) atomic] upgrades and rollbacks, although it can additionally support [https://en.wikipedia.org/wiki/Imperative_programming imperative] package and user management. In NixOS, all components of the distribution — including the [https://en.wikipedia.org/wiki/Linux_kernel kernel], installed [https://en.wikipedia.org/wiki/Package_manager packages] and system configuration files — are built by [[Nix]] from [[Wikipedia:Pure function|pure functions]] called [[Nix Expression Language|Nix expressions]].


[https://nixos.org/ NixOS] is a Linux distribution based on the [[Nix Package Manager]]. It supports reproducible and declarative system-wide configuration management as well as atomic upgrades and rollbacks, although it can additionally support imperative package and user management. In NixOS, all components of the distribution — including the kernel, installed packages and system configuration files — are built by [[Nix Package Manager|Nix]] from purely functional (that is, [[Wikipedia:Pure function|side-effect free]]) [[Nix Expression Language|Nix expressions]].
Since Nix uses [https://en.wikipedia.org/wiki/Executable binary] caching, this provides a unique compromise between the binary-oriented approach used by distributions such as Debian and the [https://en.wikipedia.org/wiki/Source_code source]-oriented approach used by distributions such as Gentoo. Binaries can be used for standard components, and custom-built packages and modules can be used automatically when a pre-built binary is not available.


Since Nix uses binary caching, this provides a unique compromise between the binary-oriented approach used by distributions such as Debian and the source-oriented approach used by distributions such as Gentoo. Binaries can be used for standard components, and custom-built packages and modules can be used automatically when a prebuilt binary is not available.
Stable NixOS releases are delivered twice a year (around the end of May and the end of November). NixOS was created by [https://edolstra.github.io/ Eelco Dolstra] and [https://en.wikipedia.org/wiki/Armijn_Hemel Armijn Hemel], and initially released in 2003. It is community developed and maintained under the stewardship of the [[Nix_Community#NixOS_Foundation|NixOS Foundation]].


Stable NixOS releases are delivered biannually. NixOS was created by Eelco Dolstra and Armijn Hemel, and initially released in 2003. It is community developed and maintained under the stewardship of the [https://nixos.org/nixos/foundation.html NixOS Foundation].
== Installation ==


== Usage ==
For a full installation guide, see the [https://nixos.org/nixos/manual/index.html#ch-installation Installation chapter of the NixOS manual]. This wiki also includes alternative or supplemental guides, such as [[NixOS as a desktop]].
 
=== Installation ===
 
For a full installation guide, see the [https://nixos.org/nixos/manual/index.html#ch-installation Installation chapter of the NixOS manual].
 
Most users will install NixOS via [https://nixos.org/nixos/download.html one of the ISO images.] Both "graphical" and "minimal" ISO variants are available for each supported architecture; the "graphical" images are suitable for users intending to install a desktop environment, and the "minimal" images are suitable for users intending to install NixOS in a server role or desiring a smaller ISO image.


The ISO images are hybrid images which can be burnt to optical media or copied raw to a USB drive and booted as-is. See the installation guide for details.
Most users will install NixOS via [https://nixos.org/download/#nixos-iso one of the ISO images.] Both "graphical" and "minimal" ISO variants are available for each supported architecture; the "graphical" images are suitable for users intending to install a desktop environment, and the "minimal" images are suitable for users intending to install NixOS in a server role or desiring a smaller ISO image. The ISO images are hybrid images which can be burnt to optical media or copied raw to a USB drive and booted as-is. See the installation guide for details.


In addition to the ISO images, the [https://nixos.org/nixos/download.html download page] provides a number of alternative methods for installing NixOS. These include:
In addition to the ISO images, the [https://nixos.org/download/#nixos-iso download page] provides a number of alternative methods for installing NixOS. These include:


* virtual appliances in OVA format (compatible with VirtualBox);
* Virtual appliances in OVA format (compatible with VirtualBox);
* Amazon EC2 AMIs;
* Amazon EC2 AMIs;
* Microsoft Azure blobs.


Additionally, many existing Linux installations can be converted into NixOS installations using [https://github.com/elitak/nixos-infect nixos-infect] or [https://github.com/jeaye/nixos-in-place nixos-in-place]; this is particularly useful for installing NixOS on hosting providers which do not natively support NixOS.
Additionally, many existing Linux installations can be converted into NixOS installations using [https://github.com/elitak/nixos-infect nixos-infect] or [https://github.com/jeaye/nixos-in-place nixos-in-place]; this is particularly useful for installing NixOS on hosting providers which do not natively support NixOS.


For information on installing NixOS on various ARM devices, see [[NixOS on ARM]].
For information on installing NixOS on various ARM devices, see [[NixOS on ARM]].
== Usage ==


=== Declarative Configuration ===
=== Declarative Configuration ===


One of NixOS's most distinguishing features is the ability to ''declaratively configure'' the whole system. This is done by specifying a configuration file which specifies the entire system state, including which packages should be installed and all the various system settings and options. This configuration file is normally located at <code>/etc/nixos/configuration.nix</code> (although another location may be specified using the environment variable <code>NIX_PATH</code>); after the configuration file is modified, the new configuration is then made active by running <code>nixos-rebuild switch</code>. The switch is atomic and can be rolled back if necessary. The configuration files under <code>/etc/nixos</code> may even be kept in a version control system such as Git if desired.
One of NixOS's most distinguishing features is the ability to ''declaratively configure'' the whole system. This is done by specifying a configuration file which specifies the entire system state, including which packages should be installed and all the various system settings and options. This configuration file is normally located at <code>/etc/nixos/configuration.nix</code> (although another location may be specified using the environment variable <code>NIX_PATH</code>, or using <code>nixos-rebuild</code>'s <code>-I</code> option to override the <code>&lt;nixos&gt;</code> [https://nix.dev/manual/nix/latest/language/constructs/lookup-path.html#lookup-path lookup path]); after the configuration file is modified, the new configuration is then made active by running <code>nixos-rebuild switch</code>. The switch is atomic and can be rolled back if necessary. Most users keep the configuration files under <code>/etc/nixos</code> in a version control system such as Git.


Conventional distributions require users to manually modify configuration files, but these changes are not tracked. If distributions change the default contents of configuration files, these changes often have to be manually merged by users if they have previously modified the file, or the distribution modifications may not be integrated at all, leading to undesired configuration drift. Configuration settings and changes are rarely recorded in a version control system. These shortcomings are often rectified after-the-fact if at all by configuration management solutions such as Puppet or Chef. These tools reconcile system configuration with a description of the expected state. However, these tools are not integrated into the operating system design and are simply layered on top, and OS configuration may still vary where an aspect of OS configuration has not been specified in the description of expected state.
Conventional distributions require users to manually modify configuration files, but these changes are not tracked. If distributions change the default contents of configuration files, these changes often have to be manually merged by users if they have previously modified the file, or the distribution modifications may not be integrated at all, leading to undesired configuration drift. Configuration settings and changes are rarely recorded in a version control system. These shortcomings are often rectified after-the-fact if at all by configuration management solutions such as Puppet or Chef. These tools reconcile system configuration with a description of the expected state. However, these tools are not integrated into the operating system design and are simply layered on top, and OS configuration may still vary where an aspect of OS configuration has not been specified in the description of expected state.
Line 36: Line 32:
By comparison, NixOS's declarative configuration system provides a fully integrated facility for OS configuration management. Failure to specify any given item of configuration results in that item having a well-defined state, rather than being allowed to drift unmonitored. Because the full system configuration is captured in the NixOS configuration system, this also makes NixOS highly suited to the automatic deployment of configuration in environments such as automated server farms; tools such as [[NixOps]] make this easy.
By comparison, NixOS's declarative configuration system provides a fully integrated facility for OS configuration management. Failure to specify any given item of configuration results in that item having a well-defined state, rather than being allowed to drift unmonitored. Because the full system configuration is captured in the NixOS configuration system, this also makes NixOS highly suited to the automatic deployment of configuration in environments such as automated server farms; tools such as [[NixOps]] make this easy.


The following is an example <code>/etc/nixos/configuration.nix</code>:
Here is a simple example of a NixOS system configuration:


<syntaxhighlight lang="nix">
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ config, pkgs, ... }:  
{ config, pkgs, ... }:  


Line 45: Line 41:
     # (hardware-configuration.nix is autogenerated upon installation)
     # (hardware-configuration.nix is autogenerated upon installation)
     # paths in nix expressions are always relative the file which defines them
     # paths in nix expressions are always relative the file which defines them
     imports =
     imports = [
         [
         ./hardware-configuration.nix
            ./hardware-configuration.nix
        ./my-dev-tools.nix
            ./my-dev-tools.nix
        ./my-desktop-env.nix
            ./my-desktop-env.nix
        ./etc.nix
            ./etc.nix
    ];
        ];


     # Name your host machine
     # Name your host machine
Line 64: Line 59:


     # Define user accounts
     # Define user accounts
     users.users =
     users.users.myuser = {
        {
      extraGroups = [ "wheel" "networkmanager" ];
            myuser =  
      isNormalUser = true;
            {
    };
                home = "/home/myuser";
                extraGroups = [ "wheel" "networkmanager" ];
                isNormalUser = true;
                uid = 1000;
            };
        };
      
      
     # Install some packages
     # Install some packages
     environment.systemPackages =  
     environment.systemPackages = with pkgs; [
            with pkgs;  
      ddate
            [
      testdisk
                ddate
    ];  
                testdisk
                zsh
            ];  
   
   
     # Enable the OpenSSH daemon
     # Enable the OpenSSH daemon
Line 88: Line 74:
      
      
}
}
</syntaxhighlight>
</nowiki>}}


For inspiration, a variety of NixOS configuration files made by community members can be found in the [[Configuration Collection]].
For inspiration, a variety of NixOS configuration files made by community members can be found in the [[Configuration Collection]].


=== Imperative Operations ===
=== Imperative Operations ===
While NixOS is typically configured declaratively as much as possible, these are a few domains where imperative operations are still necessary; these include user environment management and channel management.


====  User Environments ====
====  User Environments ====


In addition to declarative system configuration, NixOS offers the imperative <code>nix-env</code> command which can be used to install packages at the user level. Packages installed using <code>nix-env</code> are only available to the given user, and do not change system state.
In addition to declarative system configuration, NixOS users can utilize Nix's imperative <code>nix-env</code> command to install packages at the user level, without changing the system state. See the [[Nix#User Environments| user environments section of the Nix article]] for more information.
 
{| class="wikitable"
|+ Common <code>nix-env</code> Commands
|-
|Searching for packages
|<code>nix-env -qaP '.*packagename.*'</code>
|-
|Installing a package
|<code>nix-env -i packagename</code>
|-
|List installed packages
|<code>nix-env -q</code>
|-
|Uninstall packages
|<code>nix-env -e packagename</code>
|-
|Upgrade packages
|<code>nix-env -u</code>
|}


==== Channels ====
==== Channels ====


Nix ''channels'' are mechanisms for distributing Nix expressions as well as the associated binaries for them; a Nix channel corresponds to a repository in a conventional package management system. Official Nix channels are automatically updated once tests are passed in Nixpkgs' [[Hydra]] instance. It is also possible to create one's own Nix channels, but here we focus the official channels. [https://nixos.org/channels/ A full list of the available official channels is available].
NixOS, as well as Nix packages and NixOS modules are distributed through Nix channels: mechanisms for distributing Nix expressions as well as the associated binary caches for them. These channels are what determine which version of NixOS you are using, and they can be broadly categorized into ''stable'' and ''unstable'' channels, and ''large'' and ''small'' channels. Most users will want the stable/large channel, currently <code>nixos-24.05</code>. For more information on channels and how to choose them, see the [[Channel branches]] article.
 
NixOS is distributed through a number of channels. These NixOS channels can be broadly categorised into ''stable'' and ''unstable'' channels, and ''large'' and ''small'' channels:
 
* Stable/unstable:
** Stable channels (<code>nixos-17.09</code>) provide conservative updates for fixing bugs and security vulnerabilities, but do not receive major updates after initial release. New stable channels are released every six months.
** Unstable channels (<code>nixos-unstable</code>, <code>nixos-unstable-small</code>) correspond to the main development branch of Nixpkgs, delivering the latest tested updates on a rolling basis.
* Large/small:
** Large channels (<code>nixos-17.09</code>, <code>nixos-unstable</code>) provide binary builds for the full breadth of Nixpkgs.
** Small channels (<code>nixos-17.09-small</code>, <code>nixos-unstable-small</code>) are identical to large channels, but contain fewer binaries. This means they update faster, but require more to be built from source.
 
Most users will want the stable/large channel, currently <code>nixos-17.09</code>.


Like packages installed via <code>nix-env</code>, channels are managed at user-level. NixOS uses the channels set for the <code>root</code> user to update the system-wide configuration; channels set for other users control only the user environment for that user. If you wish to change the channel used by the system-level configuration (<code>/etc/nixos/configuration.nix</code>), ensure you run the correct <code>nix-channel</code> command as root:
Like packages installed via <code>nix-env</code>, channels are managed at user-level. NixOS uses the channels set for the <code>root</code> user to update the system-wide configuration; channels set for other users control only the user environment for that user. If you wish to change the channel used by the system-level configuration (<code>/etc/nixos/configuration.nix</code>), ensure you run the correct <code>nix-channel</code> command as root:
Line 154: Line 112:
| Updating all channels
| Updating all channels
|<code>nix-channel --update</code>
|<code>nix-channel --update</code>
|-
| Rollback the last update (useful if the last update breaks the <code>nixos-rebuild</code>)
|<code>nix-channel --rollback</code>
|}
|}


Note that updating channels won't cause a rebuild in itself; if you want to update channels and rebuild, you can run <code>nixos rebuild --upgrade</code> to do both in one step.
Note that updating channels won't cause a rebuild in itself; if you want to update channels and rebuild, you can run <code>nixos-rebuild --upgrade switch</code> to do both in one step.


== Internals ==
== Internals ==


=== Comparsion to traditional Linux Distributions ===
=== Comparison with traditional Linux Distributions ===


''See also: [[Nix vs. Linux Standard Base]]''
''Main Article: [[Nix vs. Linux Standard Base]]''


The main difference between to Linux Distribution is that NixOS does not follow the [https://en.wikipedia.org/wiki/Linux_Standard_Base Linux Standard Base] file system structure. On LSB-compliant systems software is stored under ''/{,usr}/{bin,lib,share}'' and configuration is generally stored in ''/etc'' .
The main difference between NixOS and other Linux distributions is that NixOS does not follow the [https://en.wikipedia.org/wiki/Linux_Standard_Base Linux Standard Base] file system structure. On LSB-compliant systems software is stored under <code>/{,usr}/{bin,lib,share}</code> and configuration is generally stored in <code>/etc</code>. Software binaries are available in the user environment if they are placed in one of the LSB's <code>/bin</code> directories. When a program references dynamic libraries it will search for the required libraries in the LSB folders (<code>/lib</code>, <code>/usr/lib</code>).


Software binaries become available for the user environment if they are placed in the bin folder of the LSB. When software is compiled with dynamic library links it will look up the required libraries in the LSB folders ( ''/usr/lib'' ) and load it.
In NixOS however <code>/lib</code> and <code>/usr/lib</code> do not exist. Instead all system libraries, binaries, kernels, firmware and configuration files are placed in the [[Nix#Nix store|Nix store]]. The files and directories in <code>/nix/store</code> are named by hashes of the information describing the built data. All of the files and directories placed in the Nix store are immutable. <code>/bin</code> and <code>/usr/bin</code> are almost absent: they contain only <code>/bin/sh</code> and <code>/usr/bin/env</code> respectively, to provide minimal compatibility with existing scripts using shebang lines. User-level environments are implemented using a large number of symbolic links to all required packages and auxiliary files. These environments are called [[Nix#Profiles|profiles]] and are stored in <code>/nix/var/nix/profiles</code>, each user having their own profiles. Structuring the system in this way is how NixOS obtains its key advantages over conventional Linux distributions, such as atomicity and rollback support.


In NixOS however this structure is not in place. Instead, user environments are essentially a number of symbolic links to all required packages and auxiliary files. These environments are stored in ''nix/var/nix/profiles'' . Each user maintains its own environment.
=== Usage of the Nix store ===
The booted system profile is stored in a similar fashion but also contains the kernel, firmware, configuration and startup files.


Because there is no standard library folder, all packages will be compiled with explicit paths to the libraries it requires. The nix package manager will ensure that the referenced paths are available in the store. The explicit pinning of library versions makes a reproducible Operating System achievable.
A lot of confusion for newcomers arises from the fact that configuration is stored in the read-only <code>/nix/store</code> tree along with all the installed packages. This fact makes it impossible to manually edit system configuration; all configuration changes must be performed by editing the <code>/etc/nixos/configuration.nix</code> file and executing <code>nixos-rebuild switch</code>. NixOS provides the [[NixOS_modules|module system]] for editing all required configurations. Users should first use [https://search.nixos.org/options the option search tool] to check if the option they need exists before attempting to manually add files or configuration via low-level NixOS features like activation scripts.


All generated binaries, libraries and configuration is stored in the read-only /nix/store path.
The system purity makes it possible to keep system configuration in a central place, without the need to edit multiple files. This configuration can be distributed or version controlled as desired. It also provides for determinism; if you provide the same inputs, the same version of Nixpkgs and the same <code>/etc/nixos/configuration.nix</code> you will get the exact same system state.


=== Usage of the Nix Store ===
=== Modules ===
A lot of confusion for newcomers arises from the fact that configuration is stored in the read-only nix store along with all the installed packages. This fact makes it impossible to manually edit system configuration, all configuration changes must be performed by editing the ''/etc/nixos/configuration.nix'' file. NixOS provides the Modules System for editing all required configurations. Users should first check if an option for the configuration they require already exist before manually adding files or configuration via low-level NixOS features like activation scripts.


The system purity makes it possible to share system configuration without the need to edit multiple files. If you provide the same inputs, same version of '''nixpkgs''' and '''configuration.nix''' you will get the exact same booted system once deployed.
The [[NixOS modules|NixOS module system]] as defined in  [[Nixpkgs]] provides the means necessary to customize the configuration of the OS. It is used to enable and customize services such as nginx, enable firmware and customize the kernel.


=== Modules ===
All module configuration is generally performed by adding options to <code>/etc/nixos/configuration.nix</code>. Most of the examples in the wiki show how this file can be used to configure the OS.
The NixOS module system as defined in  [[Nixpkgs]] provides the means necessary to customize the configuration of the Operating System. It is used to enable and customize services such as '''nginx''', enable firmware and customize the kernel.


All module-configuration is generally performed by adding the option entries into your '''configuration.nix'''. Most samples in the wiki are generally about the customization of the operating system and therefore require you to add the said options to you configuration file.
The NixOS module system implements a typing system which allows typechecking of option settings. It also enables options defined in multiple places to be merged automatically. This allows you to spread your configuration over multiple files, and the options you set across all of those files will be merged together:


NixOS modules implement a typing system which allows type validation and merging of module options which are defined in multiple places. By that you could import multiple files and update options in multiple locations:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
<code>configuration.nix</code>
<syntaxHighlight lang=nix>
{
{
   imports = [
   imports = [
Line 195: Line 150:
   ];
   ];
}
}
</syntaxHighlight>
</nowiki>}}
<code>basic-webserver.nix</code>:
{{file|/etc/nixos/basic-webserver.nix|nix|<nowiki>
<syntaxHighlight lang=nix>
{
{
   services.nginx.enable = true;
   services.nginx.enable = true;
Line 204: Line 158:
   };
   };
}
}
</syntaxHighlight>
</nowiki>}}
<code>blog.nix</code>
{{file|/etc/nixos/blog.nix|nix|<nowiki>
<syntaxHighlight lang=nix>
{
{
   services.nginx.virtualHosts."blog.example.com" = {
   services.nginx.virtualHosts."blog.example.com" = {
Line 212: Line 165:
   };
   };
}
}
</nowiki>}}
See the [https://nixos.org/nixos/manual/index.html#sec-writing-modules Modules section of the NixOS Manual] for more details.
=== Generations ===
Every time the system state is rebuilt using <code>nixos-rebuild switch</code>, a new generation is created. You can revert to the previous generation at any time, which is useful if a configuration change (or system update) turns out to be detrimental.
You can roll back via:
<syntaxHighlight lang=shell>
$ nix-env --rollback              # roll back a user environment
$ nixos-rebuild switch --rollback  # roll back a system environment
</syntaxHighlight>
NixOS also places entries for previous generations in the bootloader menu, so as a last resort you can always revert to a previous configuration by rebooting. To set the currently booted generation as the default run
<syntaxHighlight lang=shell>
$ /run/current-system/bin/switch-to-configuration boot
</syntaxHighlight>
</syntaxHighlight>


see also: [https://nixos.org/nixos/manual/index.html#sec-writing-modules NixOS Manual about writing Modules]
Because NixOS keeps previous generations of system state available in case rollback is desired, old package versions aren't deleted from your system immediately after an update. You can delete old generations manually:
 
<syntaxHighlight lang=shell>
# delete generations older than 30 days
$ nix-collect-garbage --delete-older-than 30d
 
# delete ALL previous generations - you can no longer rollback after running this
$ nix-collect-garbage -d                     
</syntaxHighlight>


=== Generations ===
List generations:
Environments are versioned via generation, every change to an environment will create a new generation. With this structure it is possible to revert changes with the help of the nix package manager. This is also true for the booted system, however a restart is required for changing the kernel.
<syntaxHighlight lang=shell>
# as root
$ nix-env --list-generations --profile /nix/var/nix/profiles/system
</syntaxHighlight>
 
Switch generations:
<syntaxHighlight lang=shell>
# as root switch to generation 204
$ nix-env --profile /nix/var/nix/profiles/system --switch-generation 204
</syntaxHighlight>


Rolling back can be done via:
delete broken generation(s):
<syntaxHighlight lang=shell>
<syntaxHighlight lang=shell>
$ nix-env --rollback # roll back a user environment
# as root delete broken generations 205 and 206
$ nixos-rebuild switch --rollback # roll back a system environment
$ nix-env --profile /nix/var/nix/profiles/system --delete-generations 205 206
</syntaxHighlight>
</syntaxHighlight>


You can configure automatic garbage collection by setting the [https://search.nixos.org/options?query=nix.gc nix.gc] options in <code>/etc/nixos/configuration.nix</code>. This is recommended, as it keeps the size of the Nix store down.


== See also ==
== See also ==


* [[NixOS Modules System]], a library for modular expression definitions which powers [[NixOS]] configuration language.
* [[NixOS modules]], a library for modular [[Overview of the Nix Expression Language#Expressions|Nix expressions]] which powers [[#Declarative Configuration|the declarative configuration of NixOS]].
* [[NixOS Testing library]], a library for creating reproducible infrastructure tests, based on [[Nixpkgs]], [[NixOS]], QEMU and Perl.
* [[NixOS VM tests]], a library for creating reproducible infrastructure tests, based on [[Nixpkgs]], [[NixOS]], QEMU and Perl.
 
* [https://github.com/ryan4yin/nixos-and-flakes-book NixOS & Flakes Book] (Ryan4yin, 2023) - 🛠️ ❤️ An unofficial NixOS & Flakes book for beginners.


[[Category:Discussion]]
[[Category:Pedias]]
[[Category:NixOS]]
[[Category:NixOS]]
[[Category:Incomplete]]
[[Category:Nix]]

Latest revision as of 08:55, 14 September 2024

NixOS is a Linux distribution based on the Nix package manager and build system. It supports declarative system-wide configuration management as well as atomic upgrades and rollbacks, although it can additionally support imperative package and user management. In NixOS, all components of the distribution — including the kernel, installed packages and system configuration files — are built by Nix from pure functions called Nix expressions.

Since Nix uses binary caching, this provides a unique compromise between the binary-oriented approach used by distributions such as Debian and the source-oriented approach used by distributions such as Gentoo. Binaries can be used for standard components, and custom-built packages and modules can be used automatically when a pre-built binary is not available.

Stable NixOS releases are delivered twice a year (around the end of May and the end of November). NixOS was created by Eelco Dolstra and Armijn Hemel, and initially released in 2003. It is community developed and maintained under the stewardship of the NixOS Foundation.

Installation

For a full installation guide, see the Installation chapter of the NixOS manual. This wiki also includes alternative or supplemental guides, such as NixOS as a desktop.

Most users will install NixOS via one of the ISO images. Both "graphical" and "minimal" ISO variants are available for each supported architecture; the "graphical" images are suitable for users intending to install a desktop environment, and the "minimal" images are suitable for users intending to install NixOS in a server role or desiring a smaller ISO image. The ISO images are hybrid images which can be burnt to optical media or copied raw to a USB drive and booted as-is. See the installation guide for details.

In addition to the ISO images, the download page provides a number of alternative methods for installing NixOS. These include:

  • Virtual appliances in OVA format (compatible with VirtualBox);
  • Amazon EC2 AMIs;

Additionally, many existing Linux installations can be converted into NixOS installations using nixos-infect or nixos-in-place; this is particularly useful for installing NixOS on hosting providers which do not natively support NixOS.

For information on installing NixOS on various ARM devices, see NixOS on ARM.

Usage

Declarative Configuration

One of NixOS's most distinguishing features is the ability to declaratively configure the whole system. This is done by specifying a configuration file which specifies the entire system state, including which packages should be installed and all the various system settings and options. This configuration file is normally located at /etc/nixos/configuration.nix (although another location may be specified using the environment variable NIX_PATH, or using nixos-rebuild's -I option to override the <nixos> lookup path); after the configuration file is modified, the new configuration is then made active by running nixos-rebuild switch. The switch is atomic and can be rolled back if necessary. Most users keep the configuration files under /etc/nixos in a version control system such as Git.

Conventional distributions require users to manually modify configuration files, but these changes are not tracked. If distributions change the default contents of configuration files, these changes often have to be manually merged by users if they have previously modified the file, or the distribution modifications may not be integrated at all, leading to undesired configuration drift. Configuration settings and changes are rarely recorded in a version control system. These shortcomings are often rectified after-the-fact if at all by configuration management solutions such as Puppet or Chef. These tools reconcile system configuration with a description of the expected state. However, these tools are not integrated into the operating system design and are simply layered on top, and OS configuration may still vary where an aspect of OS configuration has not been specified in the description of expected state.

By comparison, NixOS's declarative configuration system provides a fully integrated facility for OS configuration management. Failure to specify any given item of configuration results in that item having a well-defined state, rather than being allowed to drift unmonitored. Because the full system configuration is captured in the NixOS configuration system, this also makes NixOS highly suited to the automatic deployment of configuration in environments such as automated server farms; tools such as NixOps make this easy.

Here is a simple example of a NixOS system configuration:

/etc/nixos/configuration.nix
{ config, pkgs, ... }: 

{
    # Import other configuration modules
    # (hardware-configuration.nix is autogenerated upon installation)
    # paths in nix expressions are always relative the file which defines them
    imports = [
        ./hardware-configuration.nix
        ./my-dev-tools.nix
        ./my-desktop-env.nix
        ./etc.nix
    ];

    # Name your host machine
    networking.hostName = "mymachine"; 

    # Set your time zone.
    time.timeZone = "Europe/Utrecht";

    # Enter keyboard layout
    services.xserver.layout = "us";
    services.xserver.xkbVariant = "altgr-intl";

    # Define user accounts
    users.users.myuser = {
      extraGroups = [ "wheel" "networkmanager" ];
      isNormalUser = true;
    };
    
    # Install some packages
    environment.systemPackages = with pkgs; [
      ddate
      testdisk
    ]; 
 
    # Enable the OpenSSH daemon
    services.openssh.enable = true;
    
}

For inspiration, a variety of NixOS configuration files made by community members can be found in the Configuration Collection.

Imperative Operations

While NixOS is typically configured declaratively as much as possible, these are a few domains where imperative operations are still necessary; these include user environment management and channel management.

User Environments

In addition to declarative system configuration, NixOS users can utilize Nix's imperative nix-env command to install packages at the user level, without changing the system state. See the user environments section of the Nix article for more information.

Channels

NixOS, as well as Nix packages and NixOS modules are distributed through Nix channels: mechanisms for distributing Nix expressions as well as the associated binary caches for them. These channels are what determine which version of NixOS you are using, and they can be broadly categorized into stable and unstable channels, and large and small channels. Most users will want the stable/large channel, currently nixos-24.05. For more information on channels and how to choose them, see the Channel branches article.

Like packages installed via nix-env, channels are managed at user-level. NixOS uses the channels set for the root user to update the system-wide configuration; channels set for other users control only the user environment for that user. If you wish to change the channel used by the system-level configuration (/etc/nixos/configuration.nix), ensure you run the correct nix-channel command as root:

Common nix-channel commands
Listing current channels nix-channel --list
Adding a primary channel nix-channel --add https://nixos.org/channels/channel-name nixos
Adding other channels nix-channel --add https://some.channel/url my-alias
Remove a channel nix-channel --remove channel-alias
Updating a channel nix-channel --update channel-alias
Updating all channels nix-channel --update
Rollback the last update (useful if the last update breaks the nixos-rebuild) nix-channel --rollback

Note that updating channels won't cause a rebuild in itself; if you want to update channels and rebuild, you can run nixos-rebuild --upgrade switch to do both in one step.

Internals

Comparison with traditional Linux Distributions

Main Article: Nix vs. Linux Standard Base

The main difference between NixOS and other Linux distributions is that NixOS does not follow the Linux Standard Base file system structure. On LSB-compliant systems software is stored under /{,usr}/{bin,lib,share} and configuration is generally stored in /etc. Software binaries are available in the user environment if they are placed in one of the LSB's /bin directories. When a program references dynamic libraries it will search for the required libraries in the LSB folders (/lib, /usr/lib).

In NixOS however /lib and /usr/lib do not exist. Instead all system libraries, binaries, kernels, firmware and configuration files are placed in the Nix store. The files and directories in /nix/store are named by hashes of the information describing the built data. All of the files and directories placed in the Nix store are immutable. /bin and /usr/bin are almost absent: they contain only /bin/sh and /usr/bin/env respectively, to provide minimal compatibility with existing scripts using shebang lines. User-level environments are implemented using a large number of symbolic links to all required packages and auxiliary files. These environments are called profiles and are stored in /nix/var/nix/profiles, each user having their own profiles. Structuring the system in this way is how NixOS obtains its key advantages over conventional Linux distributions, such as atomicity and rollback support.

Usage of the Nix store

A lot of confusion for newcomers arises from the fact that configuration is stored in the read-only /nix/store tree along with all the installed packages. This fact makes it impossible to manually edit system configuration; all configuration changes must be performed by editing the /etc/nixos/configuration.nix file and executing nixos-rebuild switch. NixOS provides the module system for editing all required configurations. Users should first use the option search tool to check if the option they need exists before attempting to manually add files or configuration via low-level NixOS features like activation scripts.

The system purity makes it possible to keep system configuration in a central place, without the need to edit multiple files. This configuration can be distributed or version controlled as desired. It also provides for determinism; if you provide the same inputs, the same version of Nixpkgs and the same /etc/nixos/configuration.nix you will get the exact same system state.

Modules

The NixOS module system as defined in Nixpkgs provides the means necessary to customize the configuration of the OS. It is used to enable and customize services such as nginx, enable firmware and customize the kernel.

All module configuration is generally performed by adding options to /etc/nixos/configuration.nix. Most of the examples in the wiki show how this file can be used to configure the OS.

The NixOS module system implements a typing system which allows typechecking of option settings. It also enables options defined in multiple places to be merged automatically. This allows you to spread your configuration over multiple files, and the options you set across all of those files will be merged together:

/etc/nixos/configuration.nix
{
  imports = [
    ./basic-webserver.nix
    ./blog.nix
  ];
}
/etc/nixos/basic-webserver.nix
{
  services.nginx.enable = true;
  services.nginx.virtualHosts."example.com" = {
    root = "/var/www/example.com";
  };
}
/etc/nixos/blog.nix
{
  services.nginx.virtualHosts."blog.example.com" = {
    root = "/var/www/blog.example.com";
  };
}

See the Modules section of the NixOS Manual for more details.

Generations

Every time the system state is rebuilt using nixos-rebuild switch, a new generation is created. You can revert to the previous generation at any time, which is useful if a configuration change (or system update) turns out to be detrimental.

You can roll back via:

$ nix-env --rollback               # roll back a user environment
$ nixos-rebuild switch --rollback  # roll back a system environment

NixOS also places entries for previous generations in the bootloader menu, so as a last resort you can always revert to a previous configuration by rebooting. To set the currently booted generation as the default run

$ /run/current-system/bin/switch-to-configuration boot

Because NixOS keeps previous generations of system state available in case rollback is desired, old package versions aren't deleted from your system immediately after an update. You can delete old generations manually:

# delete generations older than 30 days
$ nix-collect-garbage --delete-older-than 30d

# delete ALL previous generations - you can no longer rollback after running this
$ nix-collect-garbage -d

List generations:

# as root
$ nix-env --list-generations --profile /nix/var/nix/profiles/system

Switch generations:

# as root switch to generation 204
$ nix-env --profile /nix/var/nix/profiles/system --switch-generation 204

delete broken generation(s):

# as root delete broken generations 205 and 206 
$ nix-env --profile /nix/var/nix/profiles/system --delete-generations 205 206

You can configure automatic garbage collection by setting the nix.gc options in /etc/nixos/configuration.nix. This is recommended, as it keeps the size of the Nix store down.

See also