about summary refs log tree commit diff
path: root/doc/manual/packages
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/packages')
-rw-r--r--doc/manual/packages/basic-package-mgmt.xml194
-rw-r--r--doc/manual/packages/binary-cache-substituter.xml70
-rw-r--r--doc/manual/packages/channels.xml57
-rw-r--r--doc/manual/packages/copy-closure.xml50
-rw-r--r--doc/manual/packages/garbage-collection.xml77
-rw-r--r--doc/manual/packages/garbage-collector-roots.xml29
-rw-r--r--doc/manual/packages/package-management.xml23
-rw-r--r--doc/manual/packages/profiles.xml158
-rw-r--r--doc/manual/packages/sharing-packages.xml19
-rw-r--r--doc/manual/packages/ssh-substituter.xml73
10 files changed, 750 insertions, 0 deletions
diff --git a/doc/manual/packages/basic-package-mgmt.xml b/doc/manual/packages/basic-package-mgmt.xml
new file mode 100644
index 000000000000..e8d1419da093
--- /dev/null
+++ b/doc/manual/packages/basic-package-mgmt.xml
@@ -0,0 +1,194 @@
+<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-basic-package-mgmt">
+
+<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.)</para>
+
+<para>You can manually download the latest version of Nixpkgs from
+<link xlink:href='http://nixos.org/nixpkgs/download.html'/>. However,
+it’s much more convenient to use the Nixpkgs
+<emphasis>channel</emphasis>, since it makes it easy to stay up to
+date with new versions of Nixpkgs. (Channels are described in more
+detail in <xref linkend="sec-channels"/>.) Nixpkgs is automatically
+added to your list of “subscribed” channels when you install
+Nix. If this is not the case for some reason, you can add it as
+follows:
+
+<screen>
+$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
+$ nix-channel --update
+</screen>
+
+</para>
+
+<note><para>On NixOS, you’re automatically subscribed to a NixOS
+channel corresponding to your NixOS major release
+(e.g. <uri>http://nixos.org/channels/nixos-14.12</uri>). A NixOS
+channel is identical to the Nixpkgs channel, except that it contains
+only Linux binaries and is updated only if a set of regression tests
+succeed.</para></note>
+
+<para>You can view the set of available packages in Nixpkgs:
+
+<screen>
+$ nix-env -qa
+aterm-2.2
+bash-3.0
+binutils-2.15
+bison-1.875d
+blackdown-1.4.2
+bzip2-1.0.2
+…</screen>
+
+The flag <option>-q</option> specifies a query operation, and
+<option>-a</option> means that you want to show the “available” (i.e.,
+installable) packages, as opposed to the installed packages. If you
+downloaded Nixpkgs yourself, or if you checked it out from GitHub,
+then you need to pass the path to your Nixpkgs tree using the
+<option>-f</option> flag:
+
+<screen>
+$ nix-env -qaf <replaceable>/path/to/nixpkgs</replaceable>
+</screen>
+
+where <replaceable>/path/to/nixpkgs</replaceable> is where you’ve
+unpacked or checked out Nixpkgs.</para>
+
+<para>You can select specific packages by name:
+
+<screen>
+$ nix-env -qa firefox
+firefox-34.0.5
+firefox-with-plugins-34.0.5
+</screen>
+
+and using regular expressions:
+
+<screen>
+$ nix-env -qa 'firefox.*'
+</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 -qas
+…
+-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>You can install a package using <literal>nix-env -i</literal>.
+For instance,
+
+<screen>
+$ nix-env -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>
+
+<note><para>When you ask Nix to install a package, it will first try
+to get it in pre-compiled form from a <emphasis>binary
+cache</emphasis>. By default, Nix will use the binary cache
+<uri>https://cache.nixos.org</uri>; it contains binaries for most
+packages in Nixpkgs. Only if no binary is available in the binary
+cache, Nix will build the package from source. So if <literal>nix-env
+-i subversion</literal> results in Nix building stuff from source,
+then either the package is not built for your platform by the Nixpkgs
+build servers, or your version of Nixpkgs is too old or too new. For
+instance, if you have a very recent checkout of Nixpkgs, then the
+Nixpkgs build servers may not have had a chance to build everything
+and upload the resulting binaries to
+<uri>https://cache.nixos.org</uri>. The Nixpkgs channel is only
+updated after all binaries have been uploaded to the cache, so if you
+stick to the Nixpkgs channel (rather than using a Git checkout of the
+Nixpkgs tree), you will get binaries for most packages.</para></note>
+
+<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 -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 -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>
+
+</chapter>
diff --git a/doc/manual/packages/binary-cache-substituter.xml b/doc/manual/packages/binary-cache-substituter.xml
new file mode 100644
index 000000000000..c6ceb9c80610
--- /dev/null
+++ b/doc/manual/packages/binary-cache-substituter.xml
@@ -0,0 +1,70 @@
+<section 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="ssec-binary-cache-substituter">
+
+<title>Serving a Nix store via HTTP</title>
+
+<para>You can easily share the Nix store of a machine via HTTP. This
+allows other machines to fetch store paths from that machine to speed
+up installations. It uses the same <emphasis>binary cache</emphasis>
+mechanism that Nix usually uses to fetch pre-built binaries from
+<uri>https://cache.nixos.org</uri>.</para>
+
+<para>The daemon that handles binary cache requests via HTTP,
+<command>nix-serve</command>, is not part of the Nix distribution, but
+you can install it from Nixpkgs:
+
+<screen>
+$ nix-env -i nix-serve
+</screen>
+
+You can then start the server, listening for HTTP connections on
+whatever port you like:
+
+<screen>
+$ nix-serve -p 8080
+</screen>
+
+To check whether it works, try the following on the client:
+
+<screen>
+$ curl http://avalon:8080/nix-cache-info
+</screen>
+
+which should print something like:
+
+<screen>
+StoreDir: /nix/store
+WantMassQuery: 1
+Priority: 30
+</screen>
+
+</para>
+
+<para>On the client side, you can tell Nix to use your binary cache
+using <option>--option extra-binary-caches</option>, e.g.:
+
+<screen>
+$ nix-env -i firefox --option extra-binary-caches http://avalon:8080/
+</screen>
+
+The option <option>extra-binary-caches</option> tells Nix to use this
+binary cache in addition to your default caches, such as
+<uri>https://cache.nixos.org</uri>. Thus, for any path in the closure
+of Firefox, Nix will first check if the path is available on the
+server <literal>avalon</literal> or another binary caches. If not, it
+will fall back to building from source.</para>
+
+<para>You can also tell Nix to always use your binary cache by adding
+a line to the <filename linkend="sec-conf-file">nix.conf</filename>
+configuration file like this:
+
+<programlisting>
+binary-caches = http://avalon:8080/ https://cache.nixos.org/
+</programlisting>
+
+</para>
+
+</section>
diff --git a/doc/manual/packages/channels.xml b/doc/manual/packages/channels.xml
new file mode 100644
index 000000000000..15c119fcb1f9
--- /dev/null
+++ b/doc/manual/packages/channels.xml
@@ -0,0 +1,57 @@
+<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="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 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 https://nixos.org/channels/nixpkgs-unstable</screen>
+
+subscribes you to a channel that always contains that latest version
+of the Nix Packages collection.  (Subscribing really just means that
+the URL is added to the file <filename>~/.nix-channels</filename>,
+where it is read by subsequent calls to <command>nix-channel
+--update</command>.) You can “unsubscribe” using <command>nix-channel
+--remove</command>:
+
+<screen>
+$ nix-channel --remove nixpkgs
+</screen>
+</para>
+
+<para>To obtain the latest Nix expressions available in a channel, do
+
+<screen>
+$ nix-channel --update</screen>
+
+This downloads and unpacks the Nix expressions in every channel
+(downloaded from <literal><replaceable>url</replaceable>/nixexprs.tar.bz2</literal>).
+It also makes the union of each channel’s Nix expressions available by
+default to <command>nix-env</command> operations (via the symlink
+<filename>~/.nix-defexpr/channels</filename>).  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>
+
+</chapter>
diff --git a/doc/manual/packages/copy-closure.xml b/doc/manual/packages/copy-closure.xml
new file mode 100644
index 000000000000..012030e3eb67
--- /dev/null
+++ b/doc/manual/packages/copy-closure.xml
@@ -0,0 +1,50 @@
+<section 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="ssec-copy-closure">
+
+<title>Copying Closures Via SSH</title>
+
+<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>
+
+However, <command>nix-copy-closure</command> is generally more
+efficient because it only copies paths that are not already present in
+the target Nix store.</para>
+
+</section>
diff --git a/doc/manual/packages/garbage-collection.xml b/doc/manual/packages/garbage-collection.xml
new file mode 100644
index 000000000000..03b8e4c976c1
--- /dev/null
+++ b/doc/manual/packages/garbage-collection.xml
@@ -0,0 +1,77 @@
+<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='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>
+
+To delete all generations older than a specified number of days
+(except the current generation), use the <literal>d</literal>
+suffix. For example,
+
+<screen>
+$ nix-env --delete-generations 14d</screen>
+
+deletes all generations older than two weeks.</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>
+
+<xi:include href="garbage-collector-roots.xml" />
+
+</chapter>
diff --git a/doc/manual/packages/garbage-collector-roots.xml b/doc/manual/packages/garbage-collector-roots.xml
new file mode 100644
index 000000000000..8338e539202f
--- /dev/null
+++ b/doc/manual/packages/garbage-collector-roots.xml
@@ -0,0 +1,29 @@
+<section 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="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>
\ No newline at end of file
diff --git a/doc/manual/packages/package-management.xml b/doc/manual/packages/package-management.xml
new file mode 100644
index 000000000000..61e55faeb311
--- /dev/null
+++ b/doc/manual/packages/package-management.xml
@@ -0,0 +1,23 @@
+<part 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='chap-package-management'>
+
+<title>Package Management</title>
+
+<partintro>
+<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>
+</partintro>
+
+<xi:include href="basic-package-mgmt.xml" />
+<xi:include href="profiles.xml" />
+<xi:include href="garbage-collection.xml" />
+<xi:include href="channels.xml" />
+<xi:include href="sharing-packages.xml" />
+
+</part>
diff --git a/doc/manual/packages/profiles.xml b/doc/manual/packages/profiles.xml
new file mode 100644
index 000000000000..4d10319abe1c
--- /dev/null
+++ b/doc/manual/packages/profiles.xml
@@ -0,0 +1,158 @@
+<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="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 firefox</screen>
+
+on a set of Nix expressions that contained Firefox 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>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>
+
+</chapter>
diff --git a/doc/manual/packages/sharing-packages.xml b/doc/manual/packages/sharing-packages.xml
new file mode 100644
index 000000000000..8465c182ee72
--- /dev/null
+++ b/doc/manual/packages/sharing-packages.xml
@@ -0,0 +1,19 @@
+<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="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>
+
+<xi:include href="binary-cache-substituter.xml" />
+<xi:include href="copy-closure.xml" />
+<xi:include href="ssh-substituter.xml" />
+
+</chapter>
diff --git a/doc/manual/packages/ssh-substituter.xml b/doc/manual/packages/ssh-substituter.xml
new file mode 100644
index 000000000000..f24f354c4c39
--- /dev/null
+++ b/doc/manual/packages/ssh-substituter.xml
@@ -0,0 +1,73 @@
+<section 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="ssec-ssh-substituter">
+
+<title>Serving a Nix store via SSH</title>
+
+<para>You can tell Nix to automatically fetch needed binaries from a
+remote Nix store via SSH. For example, the following installs Firefox,
+automatically fetching any store paths in Firefox’s closure if they
+are available on the server <literal>avalon</literal>:
+
+<screen>
+$ nix-env -i firefox --option ssh-substituter-hosts alice@avalon
+</screen>
+
+This works similar to the binary cache substituter that Nix usually
+uses, only using SSH instead of HTTP: if a store path
+<literal>P</literal> is needed, Nix will first check if it’s available
+in the Nix store on <literal>avalon</literal>. If not, it will fall
+back to using the binary cache substituter, and then to building from
+source.</para>
+
+<note><para>The SSH substituter currently does not allow you to enter
+an SSH passphrase interactively. Therefore, you should use
+<command>ssh-add</command> to load the decrypted private key into
+<command>ssh-agent</command>.</para></note>
+
+<para>You can also copy the closure of some store path, without
+installing it into your profile, e.g.
+
+<screen>
+$ nix-store -r /nix/store/m85bxg…-firefox-34.0.5 --option ssh-substituter-hosts alice@avalon
+</screen>
+
+This is essentially equivalent to doing
+
+<screen>
+$ nix-copy-closure --from alice@avalon /nix/store/m85bxg…-firefox-34.0.5
+</screen>
+
+</para>
+
+<para>You can use SSH’s <emphasis>forced command</emphasis> feature to
+set up a restricted user account for SSH substituter access, allowing
+read-only access to the local Nix store, but nothing more. For
+example, add the following lines to <filename>sshd_config</filename>
+to restrict the user <literal>nix-ssh</literal>:
+
+<programlisting>
+Match User nix-ssh
+  AllowAgentForwarding no
+  AllowTcpForwarding no
+  PermitTTY no
+  PermitTunnel no
+  X11Forwarding no
+  ForceCommand nix-store --serve
+Match All
+</programlisting>
+
+On NixOS, you can accomplish the same by adding the following to your
+<filename>configuration.nix</filename>:
+
+<programlisting>
+nix.sshServe.enable = true;
+nix.sshServe.keys = [ "ssh-dss AAAAB3NzaC1k... bob@example.org" ];
+</programlisting>
+
+where the latter line lists the public keys of users that are allowed
+to connect.</para>
+
+</section>