nix-super/doc/manual/introduction/about-nix.xml
Eelco Dolstra 802150f987
<replaceable> -> <emphasis>
Pandoc doesn't know <replaceable> so let's force it to be rendered as
italics.
2020-07-23 18:27:20 +02:00

268 lines
9.3 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="ch-about-nix">
<title>About Nix</title>
<para>Nix is a <emphasis>purely functional package manager</emphasis>.
This means that it treats packages like values in purely functional
programming languages such as Haskell — they are built by functions
that dont have side-effects, and they never change after they have
been built. Nix stores packages in the <emphasis>Nix
store</emphasis>, usually the directory
<filename>/nix/store</filename>, where each package has its own unique
subdirectory such as
<programlisting>
/nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/
</programlisting>
where <literal>b6gvzjyb2pg0…</literal> is a unique identifier for the
package that captures all its dependencies (its a cryptographic hash
of the packages build dependency graph). This enables many powerful
features.</para>
<section><title>Multiple versions</title>
<para>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 dont interfere with each other.</para>
<para>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.</para>
</section>
<section><title>Complete dependencies</title>
<para>Nix helps you make sure that package dependency specifications
are complete. In general, when youre 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 <emphasis>your</emphasis>
machine if you have the dependency installed, but not on the end
user's machine if it's not there.</para>
<para>Since Nix on the other hand doesnt install packages in “global”
locations like <filename>/usr/bin</filename> but in package-specific
directories, the risk of incomplete dependencies is greatly reduced.
This is because tools such as compilers dont search in per-packages
directories such as
<filename>/nix/store/5lbfaxb722zp…-openssl-0.9.8d/include</filename>,
so if a package builds correctly on your system, this is because you
specified the dependency explicitly. This takes care of the build-time
dependencies.</para>
<para>Once a package is built, runtime dependencies are found by
scanning binaries for the hash parts of Nix store paths (such as
<literal>r8vvq9kq…</literal>). This sounds risky, but it works
extremely well.</para>
</section>
<section><title>Multi-user support</title>
<para>Nix has multi-user support. This means that non-privileged
users can securely install software. Each user can have a different
<emphasis>profile</emphasis>, a set of packages in the Nix store that
appear in the users <literal>PATH</literal>. If a user installs a
package that another user has already installed previously, the
package wont 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.</para>
</section>
<section><title>Atomic upgrades and rollbacks</title>
<para>Since package management operations never overwrite packages in
the Nix store but just add new versions in different paths, they are
<emphasis>atomic</emphasis>. 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 its started during that period.</para>
<para>And since packages arent overwritten, the old versions are still
there after an upgrade. This means that you can <emphasis>roll
back</emphasis> to the old version:</para>
<screen>
$ nix-env --upgrade <emphasis>some-packages</emphasis>
$ nix-env --rollback
</screen>
</section>
<section><title>Garbage collection</title>
<para>When you uninstall a package like this…
<screen>
$ nix-env --uninstall firefox
</screen>
the package isnt 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
<emphasis>garbage collector</emphasis>:
<screen>
$ nix-collect-garbage
</screen>
This deletes all packages that arent in use by any user profile or by
a currently running program.</para>
</section>
<section><title>Functional package language</title>
<para>Packages are built from <emphasis>Nix expressions</emphasis>,
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 <emphasis>deterministic</emphasis>: building a Nix
expression twice should yield the same result.</para>
<para>Because its a functional language, its 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 dont conflict with
each other in the Nix store.</para>
</section>
<section><title>Transparent source/binary deployment</title>
<para>Nix expressions generally describe how to build a package from
source, so an installation action like
<screen>
$ nix-env --install firefox
</screen>
<emphasis>could</emphasis> 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 <emphasis>source deployment
model</emphasis>. 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 <emphasis>binary
cache</emphasis>, a web server that provides pre-built binaries. For
instance, when asked to build
<literal>/nix/store/b6gvzjyb2pg0…-firefox-33.1</literal> from source,
Nix would first check if the file
<uri>https://cache.nixos.org/b6gvzjyb2pg0….narinfo</uri> exists, and
if so, fetch the pre-built binary referenced from there; otherwise, it
would fall back to building from source.</para>
</section>
<!--
<section><title>Binary patching</title>
<para>In addition to downloading binaries automatically if theyre
available, Nix can download binary deltas that patch an existing
package in the Nix store into a new version. This speeds up
upgrades.</para>
</section>
-->
<section><title>Nix Packages collection</title>
<para>We provide a large set of Nix expressions containing hundreds of
existing Unix packages, the <emphasis>Nix Packages
collection</emphasis> (Nixpkgs).</para>
</section>
<section><title>Managing build environments</title>
<para>Nix is extremely useful for developers as it makes it easy to
automatically set up the build environment for a package. Given a
Nix expression that describes the dependencies of your package, the
command <command>nix-shell</command> will build or download those
dependencies if theyre 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.</para>
<para>For example, the following command gets all dependencies of the
Pan newsreader, as described by <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/networking/newsreaders/pan/default.nix">its
Nix expression</link>:</para>
<screen>
$ nix-shell '&lt;nixpkgs>' -A pan
</screen>
<para>Youre then dropped into a shell where you can edit, build and test
the package:</para>
<screen>
[nix-shell]$ tar xf $src
[nix-shell]$ cd pan-*
[nix-shell]$ ./configure
[nix-shell]$ make
[nix-shell]$ ./pan/gui/pan
</screen>
<!--
<para>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>.</para>
-->
</section>
<section><title>Portability</title>
<para>Nix runs on Linux and macOS.</para>
</section>
<section><title>NixOS</title>
<para>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
<filename>/etc</filename>). 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. For more information and downloads, see the <link
xlink:href="http://nixos.org/">NixOS homepage</link>.</para>
</section>
<section><title>License</title>
<para>Nix is released under the terms of the <link
xlink:href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">GNU
LGPLv2.1 or (at your option) any later version</link>.</para>
</section>
</chapter>