
Nix introduction, main concepts and commands
Nix is a functional package manager for Linux and other Unix systems, making the management of packages more reliable and easily reproducible.
With a traditional package manager, when a package is updated, a new version is downloaded and used to overwrite its associated files. Changes cannot be undone. If for some reason one or more files are not updated correctly during the upgrade, those files in the package will be corrupted. This can cause the entire package to not work. Also, if different packages require different versions of the same package as a dependency, at least one will break.
This article introduces what the Nix package manager is, the different distribution options, and how to get started with it. In the following article we cover installation of NixOSa Nix-based Linux distribution.
What is Nix
Nix is a functional package manager. Below are the three main advantages of using Nix over a traditional package manager:
- Nix comes along reliability: installing or upgrading one package does not break other packages. It ensures that no package is inconsistent during an upgrade. It is possible to go back to previous versions.
- Nix comes along reproducibility: packages are built by Nix in isolation from each other. This ensures that they are reproducible and have no undeclared dependencies, so if a package works on one machine, it works on another.
- Nix is declarative: Nix makes it easy to share development and build environments for projects, regardless of the programming languages and tools used.
With Nix, files are related using symbolic links. When a package is installed, symbolic links point to a location inside Nix shop directory, found in /nix/store
. When you upgrade a package, the new package files are extracted in a different location (no overwriting), the symlinks then point to the location of new files.
Using symbolic links to refer to packages has some advantages:
- No risk of corruption between dependencies: multiple versions of the same dependency can be installed
- Lower storage requirements: the same version of a dependency is not duplicated
The upgrade process for a package creates what Nix calls a generation. It is possible to roll back and roll forward through the previous generations. This leaves the system fully functional as you can always roll back to a previous generation. It is possible to save and keep any number of generations. The downside to this is the hard drive space used to store the generations, but it is possible to purge old generations.
Nix distribution
Nix can be deployed on an existing operating system, either Linux or macOS, or with NixOS using it from scratch to create a Linux system.
Implementation via NixOS
NixOS is a Linux distribution built on top of Nix. The installation of NixOS share the steps for an alternative Linux distribution: partitioning and formatting the disk before installing the operating system. The official documentation provides steps to follow to deploy Nix through NixOS installation.
Implementation on an existing operating system
Nix is supported on Linux (i686, x86_64, aarch64) and macOS (x86_64, aarch64). Below are the commands to install Nix:
-
Linux
-
MacOS:
sh <(curl -L https://nixos.org/nix/install)
Follow Official documentation for more about installing on an existing operating system.
Use of Nix
User environment
A User environment is a set of active applications. Different users can have different environments and individual users can switch between different environments. ~/.nix-profile
is a symbolic link to the current user environment.
Managing a user environment is done either via declarative configuration using Home manager or via imperative operations using nix-env
commands.
Home manager
Home manager is the preferred way to manage user environments. It allows declarative configuration of user-specific packages and files in the home directory. It is installed via the commands:
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
nix-channel --update
nix-shell '' -A install
home-manager edit
The command home-manager edit
installs Home Manager, initializes and exposes the Home Manager configuration file located at .config/nixpkgs/home.nix
.
When something is changed in the Home Manager configuration file, the command below builds and activates the configuration for the user.
Below is an edited version of the home.nix file to install the package firefox
and to configure git
.
{ config, pkgs, ... }:
{
home.username = "florent";
home.homeDirectory = "/home/florent";
home.packages = [
pkgs.firefox
];
programs.git = {
enable = true;
userName = "Florent";
userEmail = "florent@adaltas.com";
};
home.stateVersion = "22.05";
programs.home-manager.enable = true;
}
Note that alternative installation methods integrate Home Manager with the NixOS and nix-darwin configuration. This is how we deploy our systems. Follow official documentation for more details.
Nix imperative operations: nix-env
User environment, including installation and removal of packages, can be managed with nix-env
commands. Below are some of the most useful commands:
nix-env -iA <nixpkgs.pkg-name>
-
To uninstall a package:
-
How to upgrade a package:
nix-env -u <some-packages>
Example: installation of virtualenv
with Nix
Here are the steps to install the package virtualenv
using the Nix package manager.
-
Search for
virtualenv
usenix search
command:nix search virtualenv warning: using cached results; pass '-u' to update the cache * nixpkgs.pew (pew-1.2.0) Tools to manage multiple virtualenvs written in pure python * nixpkgs.python38Packages.pytest-virtualenv (python3.8-pytest-virtualenv) Create a Python virtual environment in your test that cleans up on teardown. The fixture has utility methods to ins> * nixpkgs.python38Packages.tox (python3.8-tox-3.23.0) Virtualenv-based automation of test activities * nixpkgs.python38Packages.virtualenv (python3.8-virtualenv) A tool to create isolated Python environments * nixpkgs.python38Packages.virtualenv-clone (python3.8-virtualenv-clone) Script to clone virtualenvs * nixpkgs.python38Packages.virtualenvwrapper (python3.8-virtualenvwrapper) Enhancements to virtualenv * nixpkgs.python39Packages.pytest-virtualenv (python3.9-pytest-virtualenv) Create a Python virtual environment in your test that cleans up on teardown. The fixture has utility methods to ins> * nixpkgs.python39Packages.tox (python3.9-tox-3.23.0) Virtualenv-based automation of test activities * nixpkgs.python39Packages.virtualenv (python3.9-virtualenv) A tool to create isolated Python environments * nixpkgs.python39Packages.virtualenv-clone (python3.9-virtualenv-clone) Script to clone virtualenvs * nixpkgs.python39Packages.virtualenvwrapper (python3.9-virtualenvwrapper) Enhancements to virtualenv
The search result offers several options for installing virtualenv. We chose
nixpkgs.python38Packages.virtualenv
for the following commands. -
Install
nixpkgs.python38Packages.virtualenv
- Option 1: use
nix-env
command:
nix-env -iA nix-env -iA nixpkgs.python38Packages.virtualenv
-
Option 2: use Home manager
The contents of the Home Manager configuration file include:
{ config, pkgs, ... }: { ... home.packages = [ ... nixpkgs.python38Packages.virtualenv ... ]; ... }
To apply the Home Manager configuration:
virtualenv
is installed. Below are the commands to create and activate a new named python environmentmyPythonEnv
:virtualenv myPythonEnv source myPythonEnv/bin/activate
- Option 1: use
Generation
Every time a nix-env
the operation is done, an audit of the user environment is called generation is newly created. Some commands related to generation:
-
To list generations:
nix-env --list-generations
-
To switch to a specific generation:
nix-env --switch-generation <generation-number>
-
To remove specific generations:
nix-env --delete-generations <generation-numbers separated by space>
-
To roll back to the last
nix-env
command (to the latest generation): -
To remove older generations:
nix-env --delete-generations old
Profiles
Profiles are groups of generations so that different users don't disturb each other if they don't want to. Profiles and User environments are Nix mechanisms to allow different users to use different configurations.
Derivation
A Derivation is a Nix expression that describes everything included in a package build operation (build tools, dependencies, sources, build scripts, environment variables). That's all it takes to build a package.
Channels
A channel is a git repository that contains a list of packages. Official channels are verified by Nix. Some commands related to channels:
Garbage collection
When a package is uninstalled, it is not actually deleted from the system even if no user refers to it. That way, if you happen to need it again, it won't be downloaded again. Unsuited packages are deleted with the garbage collector command:
Conclusion
Nix is a cross-platform package manager that manages dependencies efficiently. It simplifies the process of managing a user environment declaratively and makes it easy to share a user environment. However, it comes with a steep learning curve. In my experience, learning its use was worth it.
#Nix #introduction #main #concepts #commands
Source link