Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
234 lines (170 sloc) 8.64 KB
[% WRAPPER layout.tt title="About Nix" menu='nix' %]
<p>Nix is a <em>purely functional package manager</em>. 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 <em>Nix store</em>, usually the directory
<tt>/nix/store</tt>, where each package has its own unique
subdirectory such as
</p>
<pre class="code">
/nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/
</pre>
<p>
where <tt>b6gvzjyb2pg0…</tt> 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.</p>
<h3>Multiple versions</h3>
<p>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.</p>
<p>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.</p>
<h3>Complete dependencies</h3>
<p>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
component will build and work correctly on <em>your</em> machine if
you have the dependency installed, but not on the end user's machine
if it's not there.</p>
<p>Since Nix on the other hand doesn’t install packages in “global”
locations like <tt>/usr/bin</tt> 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
<tt>/nix/store/5lbfaxb722zp…-openssl-0.9.8d/include</tt>, so if a
package builds correctly on your system, this is because you specified
the dependency explicitly.</p>
<p>Runtime dependencies are found by scanning binaries for the hash
parts of Nix store paths (such as <tt>r8vvq9kq…</tt>). This may sound
risky, but it works extremely well.</p>
<h3>Multi-user support</h3>
<p>Starting at version 0.11, Nix has multi-user support. This means
that non-privileged users can securely install software. Each user
can have a different <em>profile</em>, a set of packages in the Nix
store that appear in the user’s <tt>PATH</tt>. 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.</p>
<h3>Atomic upgrades and rollbacks</h3>
<p>Since package management operations never overwrite packages in the
Nix store but just add new versions in different paths, they are
<em>atomic</em>. 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.</p>
<p>And since package aren’t overwritten, the old versions are still
there after an upgrade. This means that you can <em>roll back</em> to
the old version:</p>
<pre class="code">
<span class="nix-command">nix-env --upgrade <em>some-packages</em></span>
<span class="nix-command">nix-env --rollback</span>
</pre>
<h3>Garbage collection</h3>
<p>When you uninstall a package like this…</p>
<pre class="code">
<span class="nix-command">nix-env --uninstall firefox</span>
</pre>
<p>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 <em>garbage collector</em>:</p>
<pre class="code">
<span class="nix-command">nix-collect-garbage</span>
</pre>
<p>This deletes all packages that aren’t in use by any user profile or
by a currently running program.</p>
<h3>Functional package language</h3>
<p>Packages are built from <em>Nix expressions</em>, 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
<em>deterministic</em>: building a Nix expression twice should yield
the same result.</p>
<p>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.</p>
<h3>Transparent source/binary deployment</h3>
<p>Nix expressions generally describe how to build a package from
source, so an installation action like</p>
<pre class="code">
<span class="nix-command">nix-env --install firefox</span>
</pre>
<p><em>could</em> 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 <em>source deployment model</em>.
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 instead use a <em>binary cache</em>, a web server that
provides pre-built binaries. For instance, when asked to build
<tt>/nix/store/b6gvzjyb2pg0…-firefox-33.1</tt> from source, Nix would
first check if the file
<tt>http://cache.nixos.org/b6gvzjyb2pg0….narinfo</tt> exists, and if
so, fetch the pre-built binary referenced from there; otherwise, it
would fall back to building from source.</p>
<!--
<h3>Binary patching</h3>
<p>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.</p>
-->
<h3>Nix Packages collection</h3>
<p>We provide a large set of Nix expressions containing thousands of
existing Unix packages, the <a href="../nixpkgs"><em>Nix Packages
collection</em> (Nixpkgs)</a>.</p>
<h3>Managing build environments</h3>
<p>Nix is extremely useful for developers as it makes it easy to
automatically set up the the build environment for a package. Given a
Nix expression that describes the dependencies of your package, the
command <strong>nix-shell</strong> will build or download those
dependencies if they’re not already in your Nix store, and then start
a Bash shell in which all necessary environment variables (such as
compiler search paths) are set.</p>
<p>For example, the following command gets all dependencies of the Pan
newsreader, as described by <a
href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix">its
Nix expression</a>:</p>
<pre>
<span class="nix-command">nix-shell '&lt;nixpkgs&gt;' -A pan</span>
</pre>
<p>You’re then dropped into a shell where you can edit, build and test
the package:</p>
<pre>
<span class="nix-shell-command">tar xf $src</span>
<span class="nix-shell-command">cd pan-*</span>
<span class="nix-shell-command">./configure</span>
<span class="nix-shell-command">make</span>
<span class="nix-shell-command">./pan/gui/pan</span>
</pre>
<p>Since Nix packages are reproducible and have complete dependency
specifications, Nix makes an excellent basis for <a
href="[%root%]hydra">a continuous build system</a>.</p>
<h3>Portability</h3>
<p>Nix runs on Linux and Mac OS X.</p>
<h3>NixOS</h3>
<p>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 <tt>/etc</tt>). This means,
among other things, that it is easy to roll back the entire
configuration of the system to an earlier state. Also, users can
install software without root privileges. <a href="[%root%]">Read
more…</a></p>
<h3>License</h3>
<p>Nix is released under the terms of the <a
href="https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">GNU
LGPLv2.1 or (at your option) any later version</a>.</p>
[% END %]