Nix User's Guide

Eelco Dolstra

LogicBlox

Copyright 2004-2012 Eelco Dolstra


Table of Contents

1. Introduction
1.1. About Nix
1.2. About us
1.3. About this manual
1.4. License
1.5. More information
2. Quick Start
3. Installation
3.1. Supported platforms
3.2. Installing a binary distribution
3.3. Installing Nix from source
3.3.1. Prerequisites
3.3.2. Obtaining a source distribution
3.3.3. Building Nix from source
3.4. Security
3.4.1. Single-user mode
3.4.2. Multi-user mode
3.4.2.1. Setting up the build users
3.4.2.2. Nix store/database owned by root
3.4.2.3. Nix store/database not owned by root
3.4.2.4. Restricting access
3.5. Using Nix
4. Package Management
4.1. Basic package management
4.2. Profiles
4.3. Garbage collection
4.3.1. Garbage collector roots
4.4. Channels
4.5. One-click installs
4.6. Sharing packages between machines
5. Writing Nix Expressions
5.1. A simple Nix expression
5.1.1. The Nix expression
5.1.2. The builder
5.1.3. Composition
5.1.4. Testing
5.1.5. The generic builder
5.2. The Nix expression language
5.2.1. Values
5.2.2. Language constructs
5.2.3. Operators
5.2.4. Derivations
5.2.4.1. Advanced attributes
5.2.5. Built-in functions
5.3. The standard environment
5.3.1. Customising the generic builder
5.3.2. Debugging failed builds
6. Setting Up Distributed Builds
A. Command Reference
A.1. Common options
A.2. Common environment variables
A.3. Main commands
nix-env — manipulate or query Nix user environments
nix-instantiate — instantiate store derivations from Nix expressions
nix-store — manipulate or query the Nix store
A.4. Utilities
nix-build — build a Nix expression
nix-channel — manage Nix channels
nix-collect-garbage — delete unreachable store paths
nix-copy-closure — copy a closure to or from a remote machine via SSH
nix-hash — compute the cryptographic hash of a path
nix-install-package — install a Nix Package file
nix-prefetch-url — copy a file from a URL into the store and print its hash
nix-pull — pull substitutes from a network cache
nix-push — generate a binary cache
nix-daemon — Nix multi-user support daemon
A.5. Files
nix.conf — Nix configuration file
B. Troubleshooting
B.1. Collisions in nix-env
B.2. Too many links error in the Nix store
C. Glossary
D. Nix Release Notes
D.1. Release 1.2 (December 6, 2012)
D.2. Release 1.1 (July 18, 2012)
D.3. Release 1.0 (May 11, 2012)
D.4. Release 0.16 (August 17, 2010)
D.5. Release 0.15 (March 17, 2010)
D.6. Release 0.14 (February 4, 2010)
D.7. Release 0.13 (November 5, 2009)
D.8. Release 0.12 (November 20, 2008)
D.9. Release 0.11 (December 31, 2007)
D.10. Release 0.10.1 (October 11, 2006)
D.11. Release 0.10 (October 6, 2006)
D.12. Release 0.9.2 (September 21, 2005)
D.13. Release 0.9.1 (September 20, 2005)
D.14. Release 0.9 (September 16, 2005)
D.15. Release 0.8.1 (April 13, 2005)
D.16. Release 0.8 (April 11, 2005)
D.17. Release 0.7 (January 12, 2005)
D.18. Release 0.6 (November 14, 2004)
D.19. Release 0.5 and earlier

List of Figures

4.1. User environments

List of Tables

5.1. Operators

List of Examples

5.1. Nix expression for GNU Hello (default.nix)
5.2. Build script for GNU Hello (builder.sh)
5.3. Composing GNU Hello (all-packages.nix)
5.4. Build script using the generic build functions
5.5. Nix expression for Subversion
5.6. Passing information to a builder using toXML
5.7. XML representation produced by toXML
6.1. Remote machine configuration: remote-systems.conf

Chapter1.Introduction

Table of Contents

1.1. About Nix
1.2. About us
1.3. About this manual
1.4. License
1.5. More information

1.1.About Nix

Nix is a purely functional package manager. This means that it treats packages like values in purely functional programming languages such as Haskell — they are built by functions that don’t have side-effects, and they never change after they have been built. Nix stores packages in the Nix store, usually the directory /nix/store, where each package has its own unique subdirectory such as

/nix/store/nlc4z5y1hm8w9s8vm6m1f5hy962xjmp5-firefox-12.0

where nlc4z5… is a unique identifier for the package that captures all its dependencies (it’s a cryptographic hash of the package’s build dependency graph). This enables many powerful features.

Multiple versions

You can have multiple versions or variants of a package installed at the same time. This is especially important when different applications have dependencies on different versions of the same package — it prevents the “DLL hell”. Because of the hashing scheme, different versions of a package end up in different paths in the Nix store, so they don’t interfere with each other.

An important consequence is that operations like upgrading or uninstalling an application cannot break other applications, since these operations never “destructively” update or delete files that are used by other packages.

Complete dependencies

Nix helps you make sure that package dependency specifications are complete. In general, when you’re making a package for a package management system like RPM, you have to specify for each package what its dependencies are, but there are no guarantees that this specification is complete. If you forget a dependency, then the package will build and work correctly on your machine if you have the dependency installed, but not on the end user's machine if it's not there.

Since Nix on the other hand doesn’t install packages in “global” locations like /usr/bin but in package-specific directories, the risk of incomplete dependencies is greatly reduced. This is because tools such as compilers don’t search in per-packages directories such as /nix/store/5lbfaxb722zp…-openssl-0.9.8d/include, so if a package builds correctly on your system, this is because you specified the dependency explicitly.

Runtime dependencies are found by scanning binaries for the hash parts of Nix store paths (such as r8vvq9kq…). This sounds risky, but it works extremely well.

Multi-user support

Nix has multi-user support. This means that non-privileged users can securely install software. Each user can have a different profile, a set of packages in the Nix store that appear in the user’s PATH. If a user installs a package that another user has already installed previously, the package won’t be built or downloaded a second time. At the same time, it is not possible for one user to inject a Trojan horse into a package that might be used by another user.

Atomic upgrades and rollbacks

Since package management operations never overwrite packages in the Nix store but just add new versions in different paths, they are atomic. So during a package upgrade, there is no time window in which the package has some files from the old version and some files from the new version — which would be bad because a program might well crash if it’s started during that period.

And since package aren’t overwritten, the old versions are still there after an upgrade. This means that you can roll back to the old version:

$ nix-env --upgrade some-packages
$ nix-env --rollback

Garbage collection

When you uninstall a package like this…

$ nix-env --uninstall firefox

the package isn’t deleted from the system right away (after all, you might want to do a rollback, or it might be in the profiles of other users). Instead, unused packages can be deleted safely by running the garbage collector:

$ nix-collect-garbage

This deletes all packages that aren’t in use by any user profile or by a currently running program.

Functional package language

Packages are built from Nix expressions, which is a simple functional language. A Nix expression describes everything that goes into a package build action (a “derivation”): other packages, sources, the build script, environment variables for the build script, etc. Nix tries very hard to ensure that Nix expressions are deterministic: building a Nix expression twice should yield the same result.

Because it’s a functional language, it’s easy to support building variants of a package: turn the Nix expression into a function and call it any number of times with the appropriate arguments. Due to the hashing scheme, variants don’t conflict with each other in the Nix store.

Transparent source/binary deployment

Nix expressions generally describe how to build a package from source, so an installation action like

$ nix-env --install firefox

could cause quite a bit of build activity, as not only Firefox but also all its dependencies (all the way up to the C library and the compiler) would have to built, at least if they are not already in the Nix store. This is a source deployment model. For most users, building from source is not very pleasant as it takes far too long. However, Nix can automatically skip building from source and download a pre-built binary instead if it knows about it. Nix channels provide Nix expressions along with pre-built binaries.

Binary patching

In addition to downloading binaries automatically if they’re available, Nix can download binary deltas that patch an existing package in the Nix store into a new version. This speeds up upgrades.

Nix Packages collection

We provide a large set of Nix expressions containing hundreds of existing Unix packages, the Nix Packages collection (Nixpkgs).

Service deployment

Nix can be used not only for rolling out packages, but also complete configurations of services. This is done by treating all the static bits of a service (such as software packages, configuration files, control scripts, static web pages, etc.) as “packages” that can be built by Nix expressions. As a result, all the features above apply to services as well: for instance, you can roll back a web server configuration if a configuration change turns out to be undesirable, you can easily have multiple instances of a service (e.g., a test and production server), and because the whole service is built in a purely functional way from a Nix expression, it is repeatable so you can easily reproduce the service on another machine.

Portability

Nix should run on most Unix systems, including Linux, FreeBSD and Mac OS X.

NixOS

NixOS is a Linux distribution based on Nix. It uses Nix not just for package management but also to manage the system configuration (e.g., to build configuration files in /etc). This means, among other things, that it’s possible to easily roll back the entire configuration of the system to an earlier state. Also, users can install software without root privileges. For more information and downloads, see the NixOS homepage.

1.2.About us

Nix was originally developed at the Department of Information and Computing Sciences, Utrecht University by the TraCE project (2003-2008). The project was funded by the Software Engineering Research Program Jacquard to improve the support for variability in software systems. Further funding was provided by the NIRICT LaQuSo Build Farm project. Development is currently supported by LogicBlox.

1.3.About this manual

This manual tells you how to install and use Nix and how to write Nix expressions for software not already in the Nix Packages collection. It also discusses some advanced topics, such as setting up distributed multi-platform building.

1.4.License

Nix is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Nix is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

1.5.More information

Some background information on Nix can be found in a number of papers. The ICSE 2004 paper Imposing a Memory Management Discipline on Software Deployment discusses the hashing mechanism used to ensure reliable dependency identification and non-interference between different versions and variants of packages. The LISA 2004 paper Nix: A Safe and Policy-Free System for Software Deployment gives a more general discussion of Nix from a system-administration perspective. The CBSE 2005 paper Efficient Upgrading in a Purely Functional Component Deployment Model is about transparent patch deployment in Nix. The SCM-12 paper Service Configuration Management shows how services (e.g., web servers) can be deployed and managed through Nix. An overview of NixOS is given in the JFP article NixOS: A Purely Functional Linux Distribution. The Nix homepage has an up-to-date list of Nix-related papers.

Nix is the subject of Eelco Dolstra’s PhD thesis The Purely Functional Software Deployment Model, which contains most of the papers listed above.

Nix has a homepage at nixos.org/.

Chapter2.Quick Start

This chapter is for impatient people who don't like reading documentation. For more in-depth information you are kindly referred to the following chapters.

  1. Download a source tarball or RPM or Debian/Ubuntu package from nixos.org/. Build source distributions using the regular sequence:

    $ tar xvfj nix-version.tar.bz2
    $ ./configure
    $ make
    $ make install (as root)

    This will install the Nix binaries in /usr/local and keep the Nix store and other state in /nix. You can change the former by specifying --prefix=path. The location of the store can be changed using --with-store-dir=path. However, you shouldn't change the store location, if at all possible, since that will make it impossible to use pre-built binaries from the Nixpkgs channel and other channels. The location of the state can be changed using --localstatedir=path.

  2. You should add prefix/etc/profile.d/nix.sh to your ~/.bashrc (or some other login file).

  3. Subscribe to the Nix Packages channel.

    $ nix-channel --add nixos.org/channels/nixpkgs-unstable

  4. Download the latest Nix expressions available in the channel.

    $ nix-channel --update

    Note that this in itself doesn't download any packages, it just downloads the Nix expressions that build them and stores them somewhere (under ~/.nix-defexpr, in case you're curious). Also, it registers the fact that pre-built binaries are available remotely.

  5. See what installable packages are currently available in the channel:

    $ nix-env -qa \*
    docbook-xml-4.2
    firefox-1.0pre-PR-0.10.1
    hello-2.1.1
    libxslt-1.1.0
    ...

  6. Install some packages from the channel:

    $ nix-env -i hello firefox ... 

    This should download pre-built packages; it should not build them locally (if it does, something went wrong).

  7. Test that they work:

    $ which hello
    /home/eelco/.nix-profile/bin/hello
    $ hello
    Hello, world!
    $ firefox
    (read Slashdot or something)

  8. Uninstall a package:

    $ nix-env -e hello

  9. To keep up-to-date with the channel, do:

    $ nix-channel --update
    $ nix-env -u '*'

    The latter command will upgrade each installed package for which there is a “newer” version (as determined by comparing the version numbers).

  10. You can also install specific packages directly from your web browser. For instance, you can go to hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest and click on any link for the individual packages for your platform. Associate application/nix-package with the program nix-install-package. A window should appear asking you whether it’s okay to install the package. Say Y. The package and all its dependencies will be installed.

  11. If you're unhappy with the result of a nix-env action (e.g., an upgraded package turned out not to work properly), you can go back:

    $ nix-env --rollback

  12. You should periodically run the Nix garbage collector to get rid of unused packages, since uninstalls or upgrades don't actually delete them:

    $ nix-collect-garbage -d

Chapter3.Installation

Table of Contents

3.1. Supported platforms
3.2. Installing a binary distribution
3.3. Installing Nix from source
3.3.1. Prerequisites
3.3.2. Obtaining a source distribution
3.3.3. Building Nix from source
3.4. Security
3.4.1. Single-user mode
3.4.2. Multi-user mode
3.4.2.1. Setting up the build users
3.4.2.2. Nix store/database owned by root
3.4.2.3. Nix store/database not owned by root
3.4.2.4. Restricting access
3.5. Using Nix

3.1.Supported platforms

Nix is currently supported on the following platforms:

  • Linux (particularly on x86, x86_64, and PowerPC).

  • Mac OS X.

  • FreeBSD (only tested on Intel).

Nix is pretty portable, so it should work on most other Unix platforms as well.

3.2.Installing a binary distribution

The easiest way to install Nix is to use a binary package. Binary packages of the latest stable release are available for Fedora, Debian, Ubuntu, Mac OS X and various other systems from the Nix homepage. You can also get builds of the latest development release from our continuous build system.

For Fedora, RPM packages are available. These can be installed or upgraded using rpm -U. For example,

$ rpm -U nix-1.0-1.i386.rpm

For Debian and Ubuntu, you can download a Deb package and install it like this:

$ dpkg -i nix_1.0-1_amd64.deb

For other platforms, including Mac OS X (Darwin), FreeBSD and other Linux distributions, you can download a binary tarball. It contains Nix and all its dependencies. You should unpack it in the root directory, then run nix-finish-install:

$ cd /
$ tar xfj nix-1.1-x86_64-darwin.tar.bz2
$ nix-finish-install

After this you can delete /usr/bin/nix-finish-install.

If you plan to use Nix from a single non-root user account, it’s probably convenient to change the ownership of the entire Nix store and database to that user account. In that case, install as follows:

alice$ cd /
alice$ sudo tar xfj nix-1.1-x86_64-darwin.tar.bz2
alice$ sudo chown -R alice /nix
alice$ nix-finish-install

Nix can be uninstalled using rpm -e nix or dpkg -r nix on RPM- and Dpkg-based systems, respectively. After this you should manually remove the Nix store and other auxiliary data, if desired:

$ rm -rf /nix

3.3.Installing Nix from source

If no binary package is available, you can download and compile a source distribution.

3.3.1.Prerequisites

  • GNU Make.

  • A fairly recent version of GCC/G++. Version 2.95 and higher should work. Clang will also work.

  • Perl 5.8 or higher.

  • pkg-config to locate dependencies. If your distribution does not provide it, you can get it from www.freedesktop.org/wiki/Software/pkg-config.

  • The bzip2 compressor program and the libbz2 library. Thus you must have bzip2 installed, including development headers and libraries. If your distribution does not provide these, you can obtain bzip2 from www.bzip.org/.

  • The SQLite embedded database library, version 3.6.19 or higher. If your distribution does not provide it, please install it from www.sqlite.org/.

  • The Perl DBI and DBD::SQLite libraries, which are available from CPAN if your distribution does not provide them.

  • The Boehm garbage collector to reduce the evaluator’s memory consumption (optional). To enable it, install pkgconfig and the Boehm garbage collector, and pass the flag --enable-gc to configure.

  • The xmllint and xsltproc programs to build this manual and the man-pages. These are part of the libxml2 and libxslt packages, respectively. You also need the DocBook XSL stylesheets and optionally the DocBook 5.0 RELAX NG schemas. Note that these are only required if you modify the manual sources or when you are building from the Git repository.

  • Recent versions of Bison and Flex to build the parser. (This is because Nix needs GLR support in Bison and reentrancy support in Flex.) For Bison, you need version 2.3 or higher (1.875 does not work), which can be obtained from the GNU FTP server. For Flex, you need version 2.5.33, which is available on SourceForge. Slightly older versions may also work, but ancient versions like the ubiquitous 2.5.4a won't. Note that these are only required if you modify the parser or when you are building from the Git repository.

3.3.2.Obtaining a source distribution

The source tarball of the most recent stable release can be downloaded from the Nix homepage. You can also grab the most recent development release.

Alternatively, the most recent sources of Nix can be obtained from its Git repository. For example, the following command will check out the latest revision into a directory called nix:

$ git clone https://github.com/NixOS/nix

Likewise, specific releases can be obtained from the tags of the repository.

3.3.3.Building Nix from source

After unpacking or checking out the Nix sources, issue the following commands:

$ ./configure options...
$ make
$ make install

Nix requires GNU Make so you may need to invoke gmake instead.

When building from the Git repository, these should be preceded by the command:

$ ./bootstrap.sh

The installation path can be specified by passing the --prefix=prefix to configure. The default installation directory is /usr/local. You can change this to any location you like. You must have write permission to the prefix path.

Nix keeps its store (the place where packages are stored) in /nix/store by default. This can be changed using --with-store-dir=path.

Warning

It is best not to change the Nix store from its default, since doing so makes it impossible to use pre-built binaries from the standard Nixpkgs channels — that is, all packages will need to be built from source.

Nix keeps state (such as its database and log files) in /nix/var by default. This can be changed using --localstatedir=path.

If you want to rebuild the documentation, pass the full path to the DocBook RELAX NG schemas and to the DocBook XSL stylesheets using the --with-docbook-rng=path and --with-docbook-xsl=path options.

3.4.Security

Nix has two basic security models. First, it can be used in “single-user mode”, which is similar to what most other package management tools do: there is a single user (typically root) who performs all package management operations. All other users can then use the installed packages, but they cannot perform package management operations themselves.

Alternatively, you can configure Nix in “multi-user mode”. In this model, all users can perform package management operations — for instance, every user can install software without requiring root privileges. Nix ensures that this is secure. For instance, it’s not possible for one user to overwrite a package used by another user with a Trojan horse.

3.4.1.Single-user mode

In single-user mode, all Nix operations that access the database in prefix/var/nix/db or modify the Nix store in prefix/store must be performed under the user ID that owns those directories. This is typically root. (If you install from RPM packages, that’s in fact the default ownership.) However, on single-user machines, it is often convenient to chown those directories to your normal user account so that you don’t have to su to root all the time.

3.4.2.Multi-user mode

To allow a Nix store to be shared safely among multiple users, it is important that users are not able to run builders that modify the Nix store or database in arbitrary ways, or that interfere with builds started by other users. If they could do so, they could install a Trojan horse in some package and compromise the accounts of other users.

To prevent this, the Nix store and database are owned by some privileged user (usually root) and builders are executed under special user accounts (usually named nixbld1, nixbld2, etc.). When a unprivileged user runs a Nix command, actions that operate on the Nix store (such as builds) are forwarded to a Nix daemon running under the owner of the Nix store/database that performs the operation.

Note

Multi-user mode has one important limitation: only root can run nix-pull to register the availability of pre-built binaries. However, those registrations are shared by all users, so they still get the benefit from nix-pulls done by root.

3.4.2.1.Setting up the build users

The build users are the special UIDs under which builds are performed. They should all be members of the build users group (usually called nixbld). This group should have no other members. The build users should not be members of any other group.

Here is a typical /etc/group definition of the build users group with 10 build users:

nixbld:!:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10

In this example the nixbld group has UID 30000, but of course it can be anything that doesn’t collide with an existing group.

Here is the corresponding part of /etc/passwd:

nixbld1:x:30001:65534:Nix build user 1:/var/empty:/noshell
nixbld2:x:30002:65534:Nix build user 2:/var/empty:/noshell
nixbld3:x:30003:65534:Nix build user 3:/var/empty:/noshell
...
nixbld10:x:30010:65534:Nix build user 10:/var/empty:/noshell

The home directory of the build users should not exist or should be an empty directory to which they do not have write access.

The build users should have write access to the Nix store, but they should not have the right to delete files. Thus the Nix store’s group should be the build users group, and it should have the sticky bit turned on (like /tmp):

$ chgrp nixbld /nix/store
$ chmod 1775 /nix/store

Finally, you should tell Nix to use the build users by specifying the build users group in the build-users-group option in the Nix configuration file (usually /etc/nix/nix.conf):

build-users-group = nixbld

<">

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.