Nix package manager: Difference between revisions

From NixOS Wiki
imported>Ixxie
Moved non-root install back.
m fix nix stable manual installation link
 
(63 intermediate revisions by 24 users not shown)
Line 1: Line 1:
{{Expansion|This article is incomplete.}}


 
Nix is a package manager and build system that parses reproducible build instructions specified in the [[Nix Expression Language]], a pure functional language with lazy evaluation. Nix expressions are pure functions<ref>Values cannot change during computation. Functions always produce the same output if their input does not change. </ref>taking dependencies as arguments and producing a ''derivation'' specifying a reproducible build environment for the package. Nix stores the results of the build in unique addresses specified by a hash of the complete dependency tree, creating an immutable package store (aka the [[#Nix store|nix store]]) that allows for atomic upgrades, rollbacks and concurrent installation of different versions of a package, essentially eliminating [https://en.wikipedia.org/wiki/Dependency_hell dependency hell].  
This [[:Category:Discussion|discussion]] article is to cover the usage, internals and configuration of the Nix package manager.


== Usage ==
== Usage ==


=== Installation ===
=== Installation ===
NixOS: Nix is being installed while you install NixOS.


This section described common methods for installing Nix on Non-NixOS distributions. For alternative installation methods - including how to install Nix with a non-root account - see [[Nix Cookbook#Alternative Install Methods|the Nix Cookbook]].
If you intend to utilize Nix on a different Linux distribution or a Mac computer, you can perform a standalone installation:  The [https://nixos.org/manual/nix/stable/installation/installation installation section of the Nix manual] describes the installation of standalone Nix from binary or source.


==== Single user install ====
=== Nix commands ===


To install Nix from any Linux distribution, use the following two commands (assumes you have the permission to use sudo and you are logged in as the user you want to install Nix for).
The [[Nix command|Nix commands]] are documented in the [https://nixos.org/manual/nix/stable/command-ref/command-ref Nix reference manual]: main commands, utilities and experimental commands. Prior to version 2.0 (released in February 2018) there have been different commands.


<syntaxHighlight lang="console">
=== Configuration ===
$ sudo install -d -m755 -o $USER -g $USER /nix
On NixOS, Nix is configured through the [https://search.nixos.org/options?query=nix. <code>nix</code> option].
$ curl https://nixos.org/nix/install | sh
</syntaxHighlight>


After that being done, you can use all Nix commands as a normal user without any special permissions (for example by using <code>sudo</code>)
Standalone Nix is configured through <code>nix.conf</code> (usually found in <code>/etc/nix/</code>), which defines a number of settings relating to evaluation, builds, garbage collection, sandboxing, and user permissions. Details on the available options are [https://nixos.org/manual/nix/stable/command-ref/conf-file found in the Nix reference manual].


Even further configuration is possible with [[Home Manager]] to manage declarative environments for a single user. For system-wide configuration on Linux, you can use [https://github.com/numtide/system-manager System Manager]. For system-wide configuration on macOS, [https://github.com/LnL7/nix-darwin nix-darwin] is the preferred solution. 


==== Installing without root permissions ====
== Internals ==
 
By using [https://github.com/lethalman/nix-user-chroot nix-user-chroot] or [https://github.com/proot-me/PRoot PRoot]
you can use Nix on systems, where you have no permission to create `/nix`.
<code>nix-user-chroot</code> is the preferred and faster option. However it might not run on older linux kernels
or kernels without user namespace support. With the following command you can test
whether your system support user namespaces:
 
<syntaxHighlight lang="console">
$ unshare --user --pid echo YES
</syntaxHighlight>
 
The output should be <code>YES</code>.
If the command is absent an alternative is to check the kernel compile options.
 
<syntaxHighlight lang="console">
$ zgrep CONFIG_USER_NS /proc/config.gz
# On some systems like Debian or Ubuntu the kernel configuration is in a different place
$ grep CONFIG_USER_NS /boot/config-$(uname -r)
</syntaxHighlight>
 
If the output of this command is <code>CONFIG_USER_NS=y</code> your system supports user namespaces.
 
===== nix-user-chroot =====
 
<code>nix-user-chroot</code> will create an environment, in which you can bind mount an directory to <code>/nix</code>.
The mountpoint will be only visible within this environment.
 
<code>nix-user-chroot</code> can be build the following way. This assumes a c compiler and make is installed.
 
<syntaxHighlight lang="console">
$ git clone https://github.com/lethalman/nix-user-chroot.git
$ cd nix-user-chroot
$ make
</syntaxHighlight>
 
The last step created an executable called <code>nix-user-chroot</code>.
 
<code>nix-user-chroot</code> can be used to install nix.
In this example the nix store will be installed to <code>~/.nix</code>:
 
<syntaxHighlight lang="console">
$ mkdir -m 0755 ~/.nix
$ ./nix-user-chroot/nix-user-chroot ~/.nix bash
</syntaxHighlight>
 
This will start a new shell in which you can run the install script of nix:
 
<syntaxHighlight lang="console">
$ curl https://nixos.org/nix/install | sh
</syntaxHighlight>
 
Note that you can only use nix and the installed programs within the shell started by <code>nix-user-chroot</code>.
 
===== PRoot =====
 
Precompiled PRoot binaries can be downloaded from [https://github.com/proot-me/proot-static-build/releases here]
 
The following commands will install nix the nix store to <code>~/.nix</code>
 
<syntaxHighlight lang="console">
$ chmod +x proot_5.1.1_x86_64_rc2--no-seccomp # first make sure the executable bit is set on the binary
$ mkdir ~/.nix
$ ./proot_5.1.1_x86_64_rc2--no-seccomp ~/.nix
</syntaxHighlight>


This will start a new shell, where nix can be installed:
=== Nix store ===


<syntaxHighlight lang="console">
Packages built by Nix are placed in the read-only ''Nix store'', normally found in <code>/nix/store</code>. Each package is given a unique address specified by a cryptographic hash followed by the package name and version, for example <code>/nix/store/nawl092prjblbhvv16kxxbk6j9gkgcqm-git-2.14.1</code>. These prefixes hash all the inputs to the build process, including the source files, the full dependency tree, compiler flags, etc. This allows Nix to simultaneously install different versions of the same package, and even different builds of the same version, for example variants built with different compilers. When adding, removing or updating a package, nothing is removed from the store; instead, symlinks to these packages are added, removed or changed in ''profiles''.
$ curl https://nixos.org/nix/install | sh
</syntaxHighlight>


Note that you can only use nix and the installed programs within the shell started by PRoot.
=== Profiles ===


In order to construct a coherent user or system environment, Nix symlinks entries of the Nix store into ''profiles''. These are the front-end by which Nix allows rollbacks: since the store is immutable and previous versions of profiles are kept, reverting to an earlier state is simply a matter of change the symlink to a previous profile. To be more precise, Nix symlinks binaries into entries of the Nix store representing the user environments. These user environments are then symlinked into labeled profiles stored in <code>/nix/var/nix/profiles</code>, which are in turn symlinked to the user's <code>~/.nix-profile</code>.


=== Configuration ===
=== Sandboxing ===
 
==== Sandbox builds ====
 
When sandbox builds are enabled, Nix will setup an isolated environment for each build process. It is used to remove further hidden dependencies set by the build environment to improve reproducibility. This includes access to the network during the build outside of <code>fetch*</code> functions and files outside the Nix store.  Depending on the operating system access to other resources are blocked as well (ex. inter process communication is isolated on Linux); see [https://nixos.org/nix/manual/#description-45 build-use-sandbox] in nix manual for details.
 
Sandboxes are not enabled by default in Nix as there are cases where it makes building packages harder (for example <code>npm install</code> will not work due missing network access).
In pull requests for [https://github.com/NixOS/nixpkgs/ nixpkgs] people are asked to test builds with sandboxing enabled (see <code>Tested using sandboxing</code> in the pull request template) because in [https://nixos.org/hydra/ official hydra builds] sandboxing is also used.
 
To configure Nix for sandboxing set <code>build-use-sandbox = true;</code> in  <code>/etc/nix/nix.conf</code>; to configure NixOS for sandboxing set <code>nix.useSandbox = true;</code> in <code>configuration.nix</code>.
 
== Internals ==
 
== Development ==


== History ==
When sandbox builds are enabled, Nix will setup an isolated environment for each build process. It is used to remove further hidden dependencies set by the build environment to improve reproducibility. This includes access to the network during the build outside of <code>fetch*</code> functions and files outside the Nix store.  Depending on the operating system access to other resources are blocked as well (ex. inter process communication is isolated on Linux); see [https://nixos.org/nix/manual/#sec-conf-file nix.conf section] in the Nix manual for details.


=== Common Errors ===
Sandboxing is enabled by default on Linux, and disabled by default on macOS.
In pull requests for [https://github.com/NixOS/nixpkgs/ Nixpkgs] people are asked to test builds with sandboxing enabled (see <code>Tested using sandboxing</code> in the pull request template) because in [https://nixos.org/hydra/ official Hydra builds] sandboxing is also used.


==== Bad configuration option: gssapikexalgorithms ====
To configure Nix for sandboxing, set <code>sandbox = true</code> in <code>/etc/nix/nix.conf</code>; to configure NixOS for sandboxing set <code>nix.useSandbox = true;</code> in <code>configuration.nix</code>. The <code>nix.useSandbox</code> option is <code>true</code> by default since NixOS 17.09.


Found when using an SSH binary from Nix on typically RPM-based distros like CentOS, Fedora, Scientific Linux, Redhat, etc. '''The quick fix:''' Just comment out the configuration option in the ssh config file, you probably don't need it.
=== Alternative Interpreters ===


==== Desktop Environment does not find .desktop files ====
There is an ongoing effort to reimplement Nix, from the ground up, in Rust.


IF your DE does not look in <code>$HOME/.nix-profile/share</code> for .desktop files.
* [https://cs.tvl.fyi/depot/-/tree/tvix tvix]
You need to add that path to the <code>XDG_DATA_DIRS</code>, the position reflects precedence so files in earlier directories shadow files in later directories. This can be accomplished in various ways depending on your login manager, see [https://wiki.archlinux.org/index.php/Xprofile Arch wiki: Xprofile] for more information.
For example using <code>~/.xprofile</code> as follows:


<syntaxHighlight lang="console">
Earlier attempts can be found on [https://riir-nix.github.io/ riir-nix]
$ export XDG_DATA_DIRS=$HOME/.nix-profile/share:/usr/local/share:/usr/share
</syntaxHighlight>


Notice that you have to include the default locations on your system, otherwise they will be overwritten. Find out the proper paths using <code>echo $XDG_DATA_DIRS</code>. (Note: <code>export XDG_DATA_DIRS=$HOME/.nix-profile/share:$XDG_DATA_DIRS</code> did not work, XDG_DATA_DIRS ended up containing only <code>$HOME/.nix-profile/share:</code> which isn't even a valid path.)


==Notes==
<references />




[[Category:Discussion]]
[[Category:Pedias]]
[[Category:Nix]]
[[Category:Nix]]
[[Category:Incomplete]]
[[Category:Incomplete]]
[[Category:Software]]

Latest revision as of 19:23, 14 September 2024

Nix is a package manager and build system that parses reproducible build instructions specified in the Nix Expression Language, a pure functional language with lazy evaluation. Nix expressions are pure functions[1]taking dependencies as arguments and producing a derivation specifying a reproducible build environment for the package. Nix stores the results of the build in unique addresses specified by a hash of the complete dependency tree, creating an immutable package store (aka the nix store) that allows for atomic upgrades, rollbacks and concurrent installation of different versions of a package, essentially eliminating dependency hell.

Usage

Installation

NixOS: Nix is being installed while you install NixOS.

If you intend to utilize Nix on a different Linux distribution or a Mac computer, you can perform a standalone installation: The installation section of the Nix manual describes the installation of standalone Nix from binary or source.

Nix commands

The Nix commands are documented in the Nix reference manual: main commands, utilities and experimental commands. Prior to version 2.0 (released in February 2018) there have been different commands.

Configuration

On NixOS, Nix is configured through the nix option.

Standalone Nix is configured through nix.conf (usually found in /etc/nix/), which defines a number of settings relating to evaluation, builds, garbage collection, sandboxing, and user permissions. Details on the available options are found in the Nix reference manual.

Even further configuration is possible with Home Manager to manage declarative environments for a single user. For system-wide configuration on Linux, you can use System Manager. For system-wide configuration on macOS, nix-darwin is the preferred solution.

Internals

Nix store

Packages built by Nix are placed in the read-only Nix store, normally found in /nix/store. Each package is given a unique address specified by a cryptographic hash followed by the package name and version, for example /nix/store/nawl092prjblbhvv16kxxbk6j9gkgcqm-git-2.14.1. These prefixes hash all the inputs to the build process, including the source files, the full dependency tree, compiler flags, etc. This allows Nix to simultaneously install different versions of the same package, and even different builds of the same version, for example variants built with different compilers. When adding, removing or updating a package, nothing is removed from the store; instead, symlinks to these packages are added, removed or changed in profiles.

Profiles

In order to construct a coherent user or system environment, Nix symlinks entries of the Nix store into profiles. These are the front-end by which Nix allows rollbacks: since the store is immutable and previous versions of profiles are kept, reverting to an earlier state is simply a matter of change the symlink to a previous profile. To be more precise, Nix symlinks binaries into entries of the Nix store representing the user environments. These user environments are then symlinked into labeled profiles stored in /nix/var/nix/profiles, which are in turn symlinked to the user's ~/.nix-profile.

Sandboxing

When sandbox builds are enabled, Nix will setup an isolated environment for each build process. It is used to remove further hidden dependencies set by the build environment to improve reproducibility. This includes access to the network during the build outside of fetch* functions and files outside the Nix store. Depending on the operating system access to other resources are blocked as well (ex. inter process communication is isolated on Linux); see nix.conf section in the Nix manual for details.

Sandboxing is enabled by default on Linux, and disabled by default on macOS. In pull requests for Nixpkgs people are asked to test builds with sandboxing enabled (see Tested using sandboxing in the pull request template) because in official Hydra builds sandboxing is also used.

To configure Nix for sandboxing, set sandbox = true in /etc/nix/nix.conf; to configure NixOS for sandboxing set nix.useSandbox = true; in configuration.nix. The nix.useSandbox option is true by default since NixOS 17.09.

Alternative Interpreters

There is an ongoing effort to reimplement Nix, from the ground up, in Rust.

Earlier attempts can be found on riir-nix


Notes

  1. Values cannot change during computation. Functions always produce the same output if their input does not change.