about summary refs log tree commit diff
path: root/doc/manual/package-management.xml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/package-management.xml')
-rw-r--r--doc/manual/package-management.xml591
1 files changed, 591 insertions, 0 deletions
diff --git a/doc/manual/package-management.xml b/doc/manual/package-management.xml
new file mode 100644
index 000000000000..e1d24b14772c
--- /dev/null
+++ b/doc/manual/package-management.xml
@@ -0,0 +1,591 @@
+<chapter xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xml:id='chap-package-management'>
+
+<title>Package Management</title>
+
+
+<para>This chapter discusses how to do package management with Nix,
+i.e., how to obtain, install, upgrade, and erase packages.  This is
+the “user’s” perspective of the Nix system — people
+who want to <emphasis>create</emphasis> packages should consult
+<xref linkend='chap-writing-nix-expressions' />.</para>
+
+
+<section><title>Basic package management</title>
+
+<para>The main command for package management is <link
+linkend="sec-nix-env"><command>nix-env</command></link>.  You can use
+it to install, upgrade, and erase packages, and to query what
+packages are installed or are available for installation.</para>
+
+<para>In Nix, different users can have different “views”
+on the set of installed applications.  That is, there might be lots of
+applications present on the system (possibly in many different
+versions), but users can have a specific selection of those active —
+where “active” just means that it appears in a directory
+in the user’s <envar>PATH</envar>.  Such a view on the set of
+installed applications is called a <emphasis>user
+environment</emphasis>, which is just a directory tree consisting of
+symlinks to the files of the active applications.  </para>
+
+<para>Components are installed from a set of <emphasis>Nix
+expressions</emphasis> that tell Nix how to build those packages,
+including, if necessary, their dependencies.  There is a collection of
+Nix expressions called the Nix Package collection that contains
+packages ranging from basic development stuff such as GCC and Glibc,
+to end-user applications like Mozilla Firefox.  (Nix is however not
+tied to the Nix Package collection; you could write your own Nix
+expressions based on it, or completely new ones.)  You can download
+the latest version from <link
+xlink:href='http://nixos.org/nixpkgs/download.html' />.</para>
+
+<para>Assuming that you have downloaded and unpacked a release of Nix
+Packages, you can view the set of available packages in the release:
+
+<screen>
+$ nix-env -qaf nixpkgs-<replaceable>version</replaceable> '*'
+ant-blackdown-1.4.2
+aterm-2.2
+bash-3.0
+binutils-2.15
+bison-1.875d
+blackdown-1.4.2
+bzip2-1.0.2
+...</screen>
+
+where <literal>nixpkgs-<replaceable>version</replaceable></literal> is
+where you’ve unpacked the release.  The flag <option>-q</option>
+specifies a query operation; <option>-a</option> means that you want
+to show the “available” (i.e., installable) packages, as opposed to
+the installed packages; and <option>-f</option>
+<filename>nixpkgs-<replaceable>version</replaceable></filename>
+specifies the source of the packages.  The argument
+<literal>'*'</literal> shows all installable packages. (The quotes are
+necessary to prevent shell expansion.)  You can also select specific
+packages by name:
+
+<screen>
+$ nix-env -qaf nixpkgs-<replaceable>version</replaceable> gcc
+gcc-3.4.6
+gcc-4.0.3
+gcc-4.1.1</screen>
+
+</para>
+
+<para>It is also possible to see the <emphasis>status</emphasis> of
+available packages, i.e., whether they are installed into the user
+environment and/or present in the system:
+
+<screen>
+$ nix-env -qasf nixpkgs-<replaceable>version</replaceable> '*'
+...
+-PS bash-3.0
+--S binutils-2.15
+IPS bison-1.875d
+...</screen>
+
+The first character (<literal>I</literal>) indicates whether the
+package is installed in your current user environment.  The second
+(<literal>P</literal>) indicates whether it is present on your system
+(in which case installing it into your user environment would be a
+very quick operation).  The last one (<literal>S</literal>) indicates
+whether there is a so-called <emphasis>substitute</emphasis> for the
+package, which is Nix’s mechanism for doing binary deployment.  It
+just means that Nix knows that it can fetch a pre-built package from
+somewhere (typically a network server) instead of building it
+locally.</para>
+
+<para>So now that we have a set of Nix expressions we can build the
+packages contained in them.  This is done using <literal>nix-env
+-i</literal>.  For instance,
+
+<screen>
+$ nix-env -f nixpkgs-<replaceable>version</replaceable> -i subversion</screen>
+
+will install the package called <literal>subversion</literal> (which
+is, of course, the <link
+xlink:href='http://subversion.tigris.org/'>Subversion version
+management system</link>).</para>
+
+<para>When you do this for the first time, Nix will start building
+Subversion and all its dependencies.  This will take quite a while —
+typically an hour or two on modern machines.  Fortunately, there is a
+faster way (so do a Ctrl-C on that install operation!): you just need
+to tell Nix that pre-built binaries of all those packages are
+available somewhere.  This is done using the
+<command>nix-pull</command> command, which must be supplied with a URL
+containing a <emphasis>manifest</emphasis> describing what binaries
+are available.  This URL should correspond to the Nix Packages release
+that you’re using.  For instance, if you obtained a release from <link
+xlink:href='http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x'
+/>, then you should do:
+
+<screen>
+$ nix-pull http://nixos.org/releases/nixpkgs/nixpkgs-0.12pre11712-4lrp7j8x/MANIFEST</screen>
+
+If you then issue the installation command, it should start
+downloading binaries from <systemitem
+class='fqdomainname'>nixos.org</systemitem>, instead of building
+them from source.  This might still take a while since all
+dependencies must be downloaded, but on a reasonably fast connection
+such as a DSL line it’s on the order of a few minutes.</para>
+
+<para>Naturally, packages can also be uninstalled:
+
+<screen>
+$ nix-env -e subversion</screen>
+
+</para>
+
+<para>Upgrading to a new version is just as easy.  If you have a new
+release of Nix Packages, you can do:
+
+<screen>
+$ nix-env -f nixpkgs-<replaceable>version</replaceable> -u subversion</screen>
+
+This will <emphasis>only</emphasis> upgrade Subversion if there is a
+“newer” version in the new set of Nix expressions, as
+defined by some pretty arbitrary rules regarding ordering of version
+numbers (which generally do what you’d expect of them).  To just
+unconditionally replace Subversion with whatever version is in the Nix
+expressions, use <parameter>-i</parameter> instead of
+<parameter>-u</parameter>; <parameter>-i</parameter> will remove
+whatever version is already installed.</para>
+
+<para>You can also upgrade all packages for which there are newer
+versions:
+
+<screen>
+$ nix-env -f nixpkgs-<replaceable>version</replaceable> -u '*'</screen>
+
+</para>
+
+<para>Sometimes it’s useful to be able to ask what
+<command>nix-env</command> would do, without actually doing it.  For
+instance, to find out what packages would be upgraded by
+<literal>nix-env -u '*'</literal>, you can do
+
+<screen>
+$ nix-env ... -u '*' --dry-run
+(dry run; not doing anything)
+upgrading `libxslt-1.1.0' to `libxslt-1.1.10'
+upgrading `graphviz-1.10' to `graphviz-1.12'
+upgrading `coreutils-5.0' to `coreutils-5.2.1'</screen>
+
+</para>
+
+</section>
+
+
+<section xml:id="sec-profiles"><title>Profiles</title>
+
+<para>Profiles and user environments are Nix’s mechanism for
+implementing the ability to allow different users to have different
+configurations, and to do atomic upgrades and rollbacks.  To
+understand how they work, it’s useful to know a bit about how Nix
+works.  In Nix, packages are stored in unique locations in the
+<emphasis>Nix store</emphasis> (typically,
+<filename>/nix/store</filename>).  For instance, a particular version
+of the Subversion package might be stored in a directory
+<filename>/nix/store/dpmvp969yhdqs7lm2r1a3gng7pyq6vy4-subversion-1.1.3/</filename>,
+while another version might be stored in
+<filename>/nix/store/5mq2jcn36ldlmh93yj1n8s9c95pj7c5s-subversion-1.1.2</filename>.
+The long strings prefixed to the directory names are cryptographic
+hashes<footnote><para>160-bit truncations of SHA-256 hashes encoded in
+a base-32 notation, to be precise.</para></footnote> of
+<emphasis>all</emphasis> inputs involved in building the package —
+sources, dependencies, compiler flags, and so on.  So if two
+packages differ in any way, they end up in different locations in
+the file system, so they don’t interfere with each other.  <xref
+linkend='fig-user-environments' /> shows a part of a typical Nix
+store.</para>
+
+<figure xml:id='fig-user-environments'><title>User environments</title>
+  <mediaobject>
+    <imageobject>
+      <imagedata fileref='figures/user-environments.png' format='PNG' />
+    </imageobject>
+  </mediaobject>
+</figure>
+
+<para>Of course, you wouldn’t want to type
+
+<screen>
+$ /nix/store/dpmvp969yhdq...-subversion-1.1.3/bin/svn</screen>
+
+every time you want to run Subversion.  Of course we could set up the
+<envar>PATH</envar> environment variable to include the
+<filename>bin</filename> directory of every package we want to use,
+but this is not very convenient since changing <envar>PATH</envar>
+doesn’t take effect for already existing processes.  The solution Nix
+uses is to create directory trees of symlinks to
+<emphasis>activated</emphasis> packages.  These are called
+<emphasis>user environments</emphasis> and they are packages
+themselves (though automatically generated by
+<command>nix-env</command>), so they too reside in the Nix store.  For
+instance, in <xref linkend='fig-user-environments' /> the user
+environment <filename>/nix/store/0c1p5z4kda11...-user-env</filename>
+contains a symlink to just Subversion 1.1.2 (arrows in the figure
+indicate symlinks).  This would be what we would obtain if we had done
+
+<screen>
+$ nix-env -i subversion</screen>
+
+on a set of Nix expressions that contained Subversion 1.1.2.</para>
+
+<para>This doesn’t in itself solve the problem, of course; you
+wouldn’t want to type
+<filename>/nix/store/0c1p5z4kda11...-user-env/bin/svn</filename>
+either.  That’s why there are symlinks outside of the store that point
+to the user environments in the store; for instance, the symlinks
+<filename>default-42-link</filename> and
+<filename>default-43-link</filename> in the example.  These are called
+<emphasis>generations</emphasis> since every time you perform a
+<command>nix-env</command> operation, a new user environment is
+generated based on the current one.  For instance, generation 43 was
+created from generation 42 when we did
+
+<screen>
+$ nix-env -i subversion mozilla</screen>
+
+on a set of Nix expressions that contained Mozilla and a new version
+of Subversion.</para>
+
+<para>Generations are grouped together into
+<emphasis>profiles</emphasis> so that different users don’t interfere
+with each other if they don’t want to.  For example:
+
+<screen>
+$ ls -l /nix/var/nix/profiles/
+...
+lrwxrwxrwx  1 eelco ... default-42-link -> /nix/store/0c1p5z4kda11...-user-env
+lrwxrwxrwx  1 eelco ... default-43-link -> /nix/store/3aw2pdyx2jfc...-user-env
+lrwxrwxrwx  1 eelco ... default -> default-43-link</screen>
+
+This shows a profile called <filename>default</filename>.  The file
+<filename>default</filename> itself is actually a symlink that points
+to the current generation.  When we do a <command>nix-env</command>
+operation, a new user environment and generation link are created
+based on the current one, and finally the <filename>default</filename>
+symlink is made to point at the new generation.  This last step is
+atomic on Unix, which explains how we can do atomic upgrades.  (Note
+that the building/installing of new packages doesn’t interfere in
+any way with old packages, since they are stored in different
+locations in the Nix store.)</para>
+
+<para>If you find that you want to undo a <command>nix-env</command>
+operation, you can just do
+
+<screen>
+$ nix-env --rollback</screen>
+
+which will just make the current generation link point at the previous
+link.  E.g., <filename>default</filename> would be made to point at
+<filename>default-42-link</filename>.  You can also switch to a
+specific generation:
+
+<screen>
+$ nix-env --switch-generation 43</screen>
+
+which in this example would roll forward to generation 43 again.  You
+can also see all available generations:
+
+<screen>
+$ nix-env --list-generations</screen></para>
+
+<para>Actually, there is another level of indirection not shown in the
+figure above.  You generally wouldn’t have
+<filename>/nix/var/nix/profiles/<replaceable>some-profile</replaceable>/bin</filename>
+in your <envar>PATH</envar>.  Rather, there is a symlink
+<filename>~/.nix-profile</filename> that points to your current
+profile.  This means that you should put
+<filename>~/.nix-profile/bin</filename> in your <envar>PATH</envar>
+(and indeed, that’s what the initialisation script
+<filename>/nix/etc/profile.d/nix.sh</filename> does).  This makes it
+easier to switch to a different profile.  You can do that using the
+command <command>nix-env --switch-profile</command>:
+
+<screen>
+$ nix-env --switch-profile /nix/var/nix/profiles/my-profile
+
+$ nix-env --switch-profile /nix/var/nix/profiles/default</screen>
+
+These commands switch to the <filename>my-profile</filename> and
+default profile, respectively.  If the profile doesn’t exist, it will
+be created automatically.  You should be careful about storing a
+profile in another location than the <filename>profiles</filename>
+directory, since otherwise it might not be used as a root of the
+garbage collector (see <xref linkend='sec-garbage-collection'
+/>).</para>
+
+<para>All <command>nix-env</command> operations work on the profile
+pointed to by <command>~/.nix-profile</command>, but you can override
+this using the <option>--profile</option> option (abbreviation
+<option>-p</option>):
+
+<screen>
+$ nix-env -p /nix/var/nix/profiles/other-profile -i subversion</screen>
+
+This will <emphasis>not</emphasis> change the
+<command>~/.nix-profile</command> symlink.</para>
+
+</section>
+
+
+<section xml:id='sec-garbage-collection'><title>Garbage collection</title>
+
+<para><command>nix-env</command> operations such as upgrades
+(<option>-u</option>) and uninstall (<option>-e</option>) never
+actually delete packages from the system.  All they do (as shown
+above) is to create a new user environment that no longer contains
+symlinks to the “deleted” packages.</para>
+
+<para>Of course, since disk space is not infinite, unused packages
+should be removed at some point.  You can do this by running the Nix
+garbage collector.  It will remove from the Nix store any package
+not used (directly or indirectly) by any generation of any
+profile.</para>
+
+<para>Note however that as long as old generations reference a
+package, it will not be deleted.  After all, we wouldn’t be able to
+do a rollback otherwise.  So in order for garbage collection to be
+effective, you should also delete (some) old generations.  Of course,
+this should only be done if you are certain that you will not need to
+roll back.</para>
+
+<para>To delete all old (non-current) generations of your current
+profile:
+
+<screen>
+$ nix-env --delete-generations old</screen>
+
+Instead of <literal>old</literal> you can also specify a list of
+generations, e.g.,
+
+<screen>
+$ nix-env --delete-generations 10 11 14</screen>
+
+</para>
+
+<para>After removing appropriate old generations you can run the
+garbage collector as follows:
+
+<screen>
+$ nix-store --gc</screen>
+
+If you are feeling uncertain, you can also first view what files would
+be deleted:
+
+<screen>
+$ nix-store --gc --print-dead</screen>
+
+Likewise, the option <option>--print-live</option> will show the paths
+that <emphasis>won’t</emphasis> be deleted.</para>
+
+<para>There is also a convenient little utility
+<command>nix-collect-garbage</command>, which when invoked with the
+<option>-d</option> (<option>--delete-old</option>) switch deletes all
+old generations of all profiles in
+<filename>/nix/var/nix/profiles</filename>.  So
+
+<screen>
+$ nix-collect-garbage -d</screen>
+
+is a quick and easy way to clean up your system.</para>
+
+
+
+
+<section xml:id="ssec-gc-roots"><title>Garbage collector roots</title>
+
+<para>The roots of the garbage collector are all store paths to which
+there are symlinks in the directory
+<filename><replaceable>prefix</replaceable>/nix/var/nix/gcroots</filename>.
+For instance, the following command makes the path
+<filename>/nix/store/d718ef...-foo</filename> a root of the collector:
+
+<screen>
+$ ln -s /nix/store/d718ef...-foo /nix/var/nix/gcroots/bar</screen>
+	
+That is, after this command, the garbage collector will not remove
+<filename>/nix/store/d718ef...-foo</filename> or any of its
+dependencies.</para>
+
+<para>Subdirectories of
+<filename><replaceable>prefix</replaceable>/nix/var/nix/gcroots</filename>
+are also searched for symlinks.  Symlinks to non-store paths are
+followed and searched for roots, but symlinks to non-store paths
+<emphasis>inside</emphasis> the paths reached in that way are not
+followed to prevent infinite recursion.</para>
+
+</section>
+
+</section>
+
+
+<section xml:id="sec-channels"><title>Channels</title>
+
+<para>If you want to stay up to date with a set of packages, it’s not
+very convenient to manually download the latest set of Nix expressions
+for those packages, use <command>nix-pull</command> to register
+pre-built binaries (if available), and upgrade using
+<command>nix-env</command>.  Fortunately, there’s a better way:
+<emphasis>Nix channels</emphasis>.</para>
+
+<para>A Nix channel is just a URL that points to a place that contains
+a set of Nix expressions and a manifest.  Using the command <link
+linkend="sec-nix-channel"><command>nix-channel</command></link> you
+can automatically stay up to date with whatever is available at that
+URL.</para>
+
+<para>You can “subscribe” to a channel using
+<command>nix-channel --add</command>, e.g.,
+
+<screen>
+$ nix-channel --add http://nixos.org/channels/nixpkgs-unstable</screen>
+
+subscribes you to a channel that always contains that latest version
+of the Nix Packages collection.  (Instead of
+<literal>nixpkgs-unstable</literal> you could also subscribe to
+<literal>nixpkgs-stable</literal>, which should have a higher level of
+stability, but right now is just outdated.)  Subscribing really just
+means that the URL is added to the file
+<filename>~/.nix-channels</filename>.  Right now there is no command
+to “unsubscribe”; you should just edit that file manually
+and delete the offending URL.</para>
+
+<para>To obtain the latest Nix expressions available in a channel, do
+
+<screen>
+$ nix-channel --update</screen>
+
+This downloads the Nix expressions in every channel (downloaded from
+<literal><replaceable>url</replaceable>/nixexprs.tar.bz2</literal>)
+and registers any available pre-built binaries in every channel
+(by <command>nix-pull</command>ing
+<literal><replaceable>url</replaceable>/MANIFEST</literal>).  It also
+makes the union of each channel’s Nix expressions the default for
+<command>nix-env</command> operations.  Consequently, you can then say
+
+<screen>
+$ nix-env -u '*'</screen>
+
+to upgrade all packages in your profile to the latest versions
+available in the subscribed channels.</para>
+
+</section>
+
+
+<section xml:id="sec-one-click"><title>One-click installs</title>
+
+<para>Often, when you want to install a specific package (e.g., from
+the <link
+xlink:href="http://nixos.org/nixpkgs/">Nix
+Packages collection</link>), subscribing to a channel is a bit
+cumbersome.  And channels don’t help you at all if you want to install
+an older version of a package than the one provided by the current
+contents of the channel, or a package that has been removed from the
+channel.  That’s when <emphasis>one-click installs</emphasis> come in
+handy: you can just go to the web page that contains the package,
+click on it, and it will be installed with all the necessary
+dependencies.</para>
+
+<para>For instance, you can go to <link
+xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
+/> and click on any link for the individual packages for your
+platform.  The first time you do this, your browser will ask what to
+do with <literal>application/nix-package</literal> files.  You should
+open them with <filename>/nix/bin/nix-install-package</filename>.
+This will open a window that asks you to confirm that you want to
+install the package.  When you answer <literal>Y</literal>, the
+package and all its dependencies will be installed.  This is a binary
+deployment mechanism — you get packages pre-compiled for the selected
+platform type.</para>
+
+<para>You can also install <literal>application/nix-package</literal>
+files from the command line directly.  See <xref
+linkend='sec-nix-install-package' /> for details.</para>
+
+</section>
+
+
+<section xml:id="sec-sharing-packages"><title>Sharing packages between machines</title>
+
+<para>Sometimes you want to copy a package from one machine to
+another.  Or, you want to install some packages and you know that
+another machine already has some or all of those packages or their
+dependencies.  In that case there are mechanisms to quickly copy
+packages between machines.</para>
+
+<para>The command <command
+linkend="sec-nix-copy-closure">nix-copy-closure</command> copies a Nix
+store path along with all its dependencies to or from another machine
+via the SSH protocol.  It doesn’t copy store paths that are already
+present on the target machine.  For example, the following command
+copies Firefox with all its dependencies:
+
+<screen>
+$ nix-copy-closure --to alice@itchy.example.org $(type -p firefox)</screen>
+
+See <xref linkend='sec-nix-copy-closure' /> for details.</para>
+
+<para>With <command linkend='refsec-nix-store-export'>nix-store
+--export</command> and <command
+linkend='refsec-nix-store-import'>nix-store --import</command> you can
+write the closure of a store path (that is, the path and all its
+dependencies) to a file, and then unpack that file into another Nix
+store.  For example,
+
+<screen>
+$ nix-store --export $(nix-store -qR $(type -p firefox)) > firefox.closure</screen>
+
+writes the closure of Firefox to a file.  You can then copy this file
+to another machine and install the closure:
+
+<screen>
+$ nix-store --import &lt; firefox.closure</screen>
+
+Any store paths in the closure that are already present in the target
+store are ignored.  It is also possible to pipe the export into
+another command, e.g. to copy and install a closure directly to/on
+another machine:
+
+<screen>
+$ nix-store --export $(nix-store -qR $(type -p firefox)) | bzip2 | \
+    ssh alice@itchy.example.org "bunzip2 | nix-store --import"</screen>
+
+But note that <command>nix-copy-closure</command> is generally more
+efficient in this example because it only copies paths that are not
+already present in the target Nix store.</para>
+
+<para>Finally, if you can mount the Nix store of a remote machine in
+your local filesystem, Nix can copy paths from the remote Nix store to
+the local Nix store <emphasis>on demand</emphasis>.  For instance,
+suppose that you mount a remote machine containing a Nix store via
+<command
+xlink:href="http://fuse.sourceforge.net/sshfs.html">sshfs</command>:
+
+<screen>
+$ sshfs alice@itchy.example.org:/ /mnt</screen>
+
+You should then set the <envar>NIX_OTHER_STORES</envar> environment
+variable to tell Nix about this remote Nix store:
+
+<screen>
+$ export NIX_OTHER_STORES=/mnt/nix</screen>
+
+Then if you do any Nix operation, e.g.
+
+<screen>
+$ nix-env -i firefox</screen>
+
+and Nix has to build a path that it sees is already present in
+<filename>/mnt/nix</filename>, then it will just copy from there
+instead of building it from source.</para>
+
+
+</section>
+
+
+</chapter>