Introduction à Nix et NixOS

NixOS est une distribution Linux sortie initialement en 2003 et créée par (Eelco Dolstra, un chercheur travaillant sur la création d’un système immuable. Celle-ci se base sur le gestionnaire de paquet Nix qui permet de gérer la configuration du système à l’aide de fichiers Nix (un langage de programmation similaire au Haskell).

Ainsi si je souhaite créer un utilisateur kiko sur mon système, je peux écrire ceci dans mon fichier configuration.nix (qui est le fichier de configuration de l’OS initial)

  users.users.kiko = {
    isNormalUser = true;
    description = "kiko";
    extraGroups = [ "networkmanager" "wheel" "sudo" ];
    packages = with pkgs; [
      firefox
      vim
      neovim
      kubectl
      terraform
    ];
  };

Ou si je veux installer des programmes dans le système, je peux écrire ça :

  environment.systemPackages = with pkgs; [
   vim
   wget
   htop
 ];

Et là, si vous êtes habitués aux gestionnaires de paquets normaux : vous avez remarqué que mon utilisateur peut installer des librairies de manière autonome.

C’est l’un des points forts de Nix ! Des environnements éphémères, des librairies contradictoires qui peuvent cohabiter, et des utilisateurs entièrements indépendants.

Nix (nous parlons du gestionnaire de paquets) autorise chaque utilisateur à avoir son propre PATH (ex: /run/wrappers/bin:/home/kiko/.nix-profile/bin:/etc/profiles/per-user/kiko/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin). Mais il ne se limite pas qu’à ça : on peut créer des environnements temporaires assez rapidement pour ne pas avoir à installer un programme et pouvoir s’en servir ponctuellement.

❯ cowsay
The program 'cowsay' is not in your PATH. It is provided by several packages.
You can make it available in an ephemeral shell by typing one of the following:
  nix-shell -p cowsay
  nix-shell -p neo-cowsay

~ 
❯ nix-shell -p cowsay
this path will be fetched (0.01 MiB download, 0.05 MiB unpacked):
  /nix/store/9647mfqndy0aa8qkniqa05qc9yi575ny-cowsay-3.04
copying path '/nix/store/9647mfqndy0aa8qkniqa05qc9yi575ny-cowsay-3.04' from 'https://cache.nixos.org'...

~ via ❄️  impure (shell) 
❯ cowsay "J aime la bidouille"
 _____________________ 
< J aime la bidouille >
 --------------------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

~ via ❄️  impure (shell) 
❯ exit
exit

~ took 44s 
❯ cowsay
The program 'cowsay' is not in your PATH. It is provided by several packages.
You can make it available in an ephemeral shell by typing one of the following:
  nix-shell -p cowsay
  nix-shell -p neo-cowsay

Nous avons créé un environnement similaire au notre.. mais avec le binaire cowsay.

Mais nous avons parlé d’environnement, alors créons un réel nix-shell plus complet…

Nix-Shell

Créons 2 fichiers.

# default.nix
with (import <nixpkgs> {});
let
  my-python-packages = python-packages: with python-packages; [
    requests
  ];
  python-with-my-packages = python3.withPackages my-python-packages;
in
mkShell {
  buildInputs = [
    python-with-my-packages
  ];
}
# app.py
import requests
response = requests.get('http://perdu.com')
print(response.content)

Le fichier app.py est notre très complèxe application tandis que le fichier default.nix décrit l’environnement requis. Si je lance directement l’application python3 app.py je me retrouve avec une erreur car je n’ai pas installé python3 dans mon environnement.. Je peux créer un nix-shell avec python et lancer mon app.py :

❯ nix-shell -p python38 # création d'un env avec python3.8

/tmp/python via 🐍 v3.8.13 via ❄️  impure (shell) 
❯ python3 app.py 
Traceback (most recent call last):
  File "app.py", line 1, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'

Mais nous nous retrouvons avec un autre problème de dépendance.. Il est donc possible de créer notre environnement à l’aide du fichier default.nix qui contiendra Python et la librairie requests (indispensable pour notre application.

Par défaut, nix-shell va chercher les fichiers nommés default.nix dans notre répertoire courant.

/tmp/python via 🐍 took 5m28s 
❯ nix-shell 

/tmp/python via 🐍 v3.9.13 via ❄️  impure (nix-shell) 
❯ python3 app.py 
b"<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1><h2>Pas de panique, on va vous aider</h2><strong><pre>    * <----- vous &ecirc;tes ici</pre></strong></body></html>\n"

Avec cette méthode, il est possible d’avoir plusieurs environnements pour lancer des applications différentes sans se soucier des effets de bords sur nos autres programmes.

Home-Manager

Si jamais je résume ce que nous avons vu :

  • Comment NixOS peut automatiser une configuration d’OS (On pourrait voir comment l’installer de la même manière)
  • Comment créer des environnements indépendants Il reste un aspect essentiel au passage sur Nix: le déploiement d’une configuration utilisateur !

Nix permet de déployer bien plus que quelques programmes, il existe une librairie d’instruction pour faciliter la configuration/déploiement d’un logiciel. Par exemple, à la création de mon utilisateur quotidien, je dois parametrer Git avec mon nom, et mon mail avant chaque commit..

git config --global user.name "Toto"
git config --global user.email "toto@toto.com"

Avec Nix, je peux créer un fichier dans mon home et garder cette configuration en dur :

  programs = {
    git = {
    enable = true;
    userName = "Toto";
    userEmail = "toto@toto.com";
    ignores =  [
      "*~"
      "*.swp"
     ];
    };
  };

J’ai donc plusieurs fichiers Nix me permettant d’installer mes programmes, de configurer Git, d’installer mon EMacs-Doom avec mes paramètres, de déposer mes dotfiles aux bons endroits. Pour l’instant.. ma configuration est publique et disponible ici, à voir ce que j’en ferai à l’avenir.. :)

Conclusion

Nix est vaste, très vaste, et il peut être compliqué d’en apprendre les bases. La communauté est au courant du manque de documentation et fait beaucoup d’effort pour donner une image agréable à Nix pour les débutants. Je pense que Nix a un potentiel non-négligeable pour les workstations/serveurs et pourrait même remplacer des outils de déploiement d’OS comme Packer.

On peut trouver les instructions / packages sur l’incroyable site search.nix.org. Je pense continuer à apprendre Nix jusqu’à pouvoir moi-même contribuer à la communauté et maintenir mes propres packages.

Seule complexité : il est nécessaire d’apprendre le langage Nix ! Mais avez-vous entendu parler de Guix.. ?