Getting Started with Nix
========================
.. role:: bash(code)
:language: bash
This section introduces basic Nix usage.
- Install packages into the system through user profiles.
- Manipulate and select channels.
- Search for packages.
Nix vs traditional package managers
-----------------------------------
*Installing* a package with a traditional package manager (e.g., apt_ or pacman_) involves several parts.
- Getting the package content — either by downloading it from a cache or by rebuilding it.
- Making the package available to the user.
These two parts are very close with the aforementioned package managers,
as the way to make packages available to the user is to rely on some standard (or distribution-specific) directories.
For example, executable files may be put into ``/usr/bin``, libraries in ``/usr/lib`` and C include files in ``/usr/include``.
The approach taken by Nix is different.
Nix stores all packages into a common place called the *Nix store*, usually located at ``/nix/store``.
Each package is stored in a unique subdirectory in the *store*, and each package has its own tree structure.
For example, a SimGrid package might be stored in ``/nix/store/l5rah62vpsr3ap63xmk197y0s1l6g2zx-simgrid-3.22.2``.
The package path is composed of a cryptographic hash of *all* the package *inputs* followed by the package name (more information about this can be found in `Nix pills about store paths`_).
The package file structure looks like the following.
.. code-block:: text
.
├── bin
| ├── smpicc
| ├── smpirun
| └── ...
├── include
│ └── ...
├── lib
│ ├── libsimgrid.so
│ └── ...
└── share
└── ...
This storage system has very interesting properties, such as allowing the simultaneous presence of as many versions of a package as desired.
However, it makes the "Making the package available to the user" more complex.
Nix heavily relies on environment variables to make this possible.
For example, an environment that contains the aforementioned SimGrid package and another ``hello`` package would put both ``/nix/store/l5rah62vpsr3ap63xmk197y0s1l6g2zx-simgrid-3.22.2/bin`` and ``/nix/store/06vykrz1hmxgxir8i74fwjl6r9bb2gpg-hello-2.10/bin`` into a ``$PATH`` environment variable.
As managing such environment variables manually would be tedious, Nix propose many commands that manage them for you.
Profiles
--------
Nix profiles are an abstraction that solves the "Making the package available to the user" issue discussed above.
A profile describes an environment, that is to say a set of packages that are made available to the user.
Managing profiles is mostly done with the ``nix-env`` command.
Curious readers may be interested in `Nix's official profile documentation`_ for an explanation about how profiles work internally.
.. To make the usage of nix user-friendly, Nix proposes the user profiles, which can be described as a user environment, and the command `nix-env` enables to interact with the profiles.
.. A profile is just a folder with a list of paths, which are packages currently installed.
.. Once you have nix installed on your system, you can start by installing your first application.
.. To start using Nix, and installing packages on your default profile you can type:
To install a package on your default profile, you can type:
.. code-block:: bash
nix-env -i package_name
For instance, to install the fortune teller application, use ``nix-env -i fortune-mod``.
To obtain the list of the packages installed in the current profile, you can use the command:
.. code-block:: bash
nix-env --query "*"
You can remove an installed package from your current profile with:
.. code-block:: bash
nix-env -e package_name
.. warning::
It is possible to remove several packages with a wildcard: ``nix-env -e "*"``.
However, this command will also remove the package ``nix`` itself from the current profile.
As a result, the current Nix profile will require a manual intervention to be recovered, as Nix commands will not be callable as usual.
A last profile feature worth mentioning here is the ability to go back to the previous generation (a new `generation` is created at each modification of the profile):
.. code-block:: bash
nix-env --rollback
Channels
--------
.. _section-description-1:
The packages available in Nix are defined in a git repository that contains the definition of all the packages (see `Nixpkgs source code`_).
A **channel**, can be seen as a `nixpkgs` branch (as in git_ branch) that is validated by a continuous integration system.
Several channels exists, the list of the currently available channels is available `here `_.
.. warning::
In this section we introduce the channel fonctionnality of the Nix package manager as it is a convenient way to interact with the package manager, and it will give you a better understanding of what is happening under the hood.
However, using channels is not fully reproducible, as a channel may evolve to incorporate updates.
When package reproducibility become a major concern, as it is the case in this tutorial, it is preferable to refer to a pinned version of the `nixpkgs` repository instead — i.e, a specific commit of the repository or an immutable archived tarball.
The ability to pin the version of nixpkgs is powerful, it will ensure that a package is always constructed from the same Nix source.
As we go deeper in the tutorial we avoid using channels in favor of pinned environments.
To list the channel currently installed **on your system**.
.. code-block:: bash
nix-channel --list
#