Introduction
Avant de commencer, je tiens à dire que j’ai fait ce post en partie pour l’entreprise Unova où je travaillais. Je tiens à les remercier pour m’avoir autorisé à réutiliser le contenu sur mon site.
Nix est un gestionnaire de paquets basé sur le langage Nix. Il permet de gérer facilement une configuration système, d’un projet ou même d’un package (logiciel) et surtout de s’assurer de la reproductibilité de la configuration. Cependant, par défaut, Nix ne permet pas de “lock” la version de la configuration sur l’ensemble des machines. C’est pour cela que les développeurs développent Flake.
Flake est une feature experimentale qui permet de lock les dépendances sur une version très précise. Un peu comme le Gemfile.lock ou même le package-lock.json.
Grâce au coté déclaratif de Nix, on peut par exemple facilement tester un outils sans devoir l’installer de manière permanente sur sa machine avec :
|
|
Ou même configurer son shell existant pour pouvoir développer sur un logiciel
|
|
Attention: Il créer un shell avec les outils nécessaires pour travailler dessus, mais ne récupère pas le projet en lui-même.
Le langage Nix
Nix est un langage de programmation dédié pour la configuration d’une machine ou compilation de programme donc il peut être compliqué à prendre en main.
Il est différent des langages traditionnels, on peut le voir comme un language de construction d’un attribut set
qui sera utilisé ensuite.
Un
attribut set
peut-être vu comme un objet JS.
1
{ a = 12; b = 14; }
Je ferrais surement un post pour expliquer plus en détail le langage car il est assez complexe. J’ai rajouté quelques liens utiles ici
Structure d’un Flake
Partie inputs
|
|
Dans cette exemple, on peut voir que j’ai rajouté les dépendances nixpkgs
et flake-utils
.
La dépendance nixpkgs
correspond au repo github nixpkgs. En général, on l’utilise pour récupérer des packages ou utiliser les outils mis à disposition par les contributeurs de NixOS.
On peut retrouver dans le repo.
/nixos
Contiens la configuration pour nixos (La distribution basée sur Nix)/pkgs
Contiens tous les packages (ex: ruby_3_3)
Les nouveaux packages doivent être mis dans le sous-dossier
by-name
. C’est un nouveau standard du projet. Les packages déjà existants migrent dessus petit à petit. Si un package manque, n’hésitez surtout pas à contribuer au projet.
lib
Contiens plein d’outils pratiques commemakeLibraryPath
oumakeIncludePath
doc
Contiens la doc ^^maintainers
Contiens la liste de tous les mainteneurs des packages.
La dépendance flake-utils
contient des helpers pour faciliter la configuration pour un ensemble de systèmes (x86_64-linux
, x86_64-darwin
, …).
darwin
Correspond au système Mac OS
Partie outputs
Outputs est une fonction qui prend en paramètre un attribute set
avec pour attributs self et les dépendances déclarées dans la partie inputs
.
Dans le cas ou l’on a les dépendances suivantes:
|
|
On aura les entrées suivantes dans outputs
:
|
|
Les attributs que l’on peut retrouver dans outputs
sont:
devShells
Des environnements de développement.nixosConfigurations
Des configurations de NixOS (La distribution Linux)darwinConfigurations
Des configurations pour Mac OS En savoir pluspackages
Des packages (Docker, ruby, go, rust, …)[...]
Exemple de flake
Dans cette example, j’ai déclaré un environnement de travail utilisable avec la commande nix develop
.
J’ai rajouté en dépendances la librairie openssl
, la commande redis
et un script au lancement du shell.
|
|
Mettre à jour le flake.lock
Le flake.nix vient avec un fichier flake.lock qui permet de vérrouiller la version de chaque input. Si on souhaite mettre à jour nos packages pour notre projet. Il est nécessaire de le mettre à jour.
On retrouve deux commandes:
nix flake update
Mets à jour tous les inputsnix flake lock --update-input <input>
Mets à jour uniquement un input en particulier
Débugger sa configuration avec la console nix
Il existe une console depuis la version expérimentale de nix nix-command
. On peut y accéder avec la commande nix repl
.
Normalement, on doit avoir un shell comme ci-dessous
|
|
Dedans, on peut écrire n’importe quoi en nix mais aussi lui demander de charger notre configuration flake avec l’aide de la commande :lf [path racine ou ce trouve le flake]
lf
est l’abréviation deLoad Flake
|
|
Une fois chargé, on peut accéder aux outputs avec outputs.<type de conf>.<system>.<nom>
Tips : Vous pouvez appuyer deux fois sur Tab pour avoir de l’aide.
Vous pouvez aussi facilement vérifier votre configuration nix avec la commande
1
nix flake check .
Fonctionnement des environnements de développement
Utiliser un devShell
Les devShells permettent de configurer des environnements par défaut.
On peut y accéder avec l’aide de la commande nix develop [path du flake]#[nom de l'environnement]
.
Ex: nix develop .#default
Le path par défaut est déjà le répertoire courant et la configuration utilisée par défaut est également default Donc la commande
nix develop
suffit dans notre cas, mais si on configure par exempleoutputs.devShells.<system>.monshell
. Dans ce cas, il faudra utilisernix develop .#monshell
ounix develop /home/user/monflake#monshell
On peut accéder aux environnements utilisés pour développer n’importe quel package nix. Par exemple, si l’on souhaite aider au développement de ruby. On peut lancer une console de développement avec la commande nix develop nixpkgs#ruby
ou même voir la configuration d’un package avec nix edit nixpkgs#ruby
On remarquera qu’ici j’utilise
nixpkgs
et pas le path du flake. Ça permet d’utiliser la configuration d’un package depuis nixpkgs directement.Attention Pour des logiciels compilés, en général, il faut d’abord configurer le compilateur via les
phases
du logiciel. ex:configurePhase
et ensuite compiler le logiciel ex:buildPhase
. Les phases peuvent varier en fonction du logiciel.
Configurer son propre devShell
Voici une configuration de shell avec des commentaires pour expliquer le fonctionnement.
|
|
Liens utiles
Pour apprendre nix
Pour trouver des packages
Repository officiel de nixpkgs
Pour connaître l’état d’une Pull Request