Une belle histoire
Debian, on connaît tous. Mère de nombreuses distributions modernes, je l’utilise depuis 13 ans. Rien qu’avec cette phrase, j’ai pris un coup de vieux.
J’ai débuté avec Debian stable, en supprimant le dual boot pour me forcer à rester sous Linux. Après un passage sous Ubuntu, je suis revenu sur Debian testing, qui cochait toutes les cases : ça marche, les paquets sont récents, pas de question à se poser.
Assez vite, j’ai voulu automatiser l’installation et la configuration de mes machines pour ne pas perdre une journée à chaque réinstallation et partager mes configurations entre ordinateurs. J’ai tout passé sous Ansible (j’en ai parlé ici). C’est un peu lourd, mais en 4 ans je n’ai eu aucun souci majeur.
Le problème
Si tout roulait au quotidien, un souci prenait de plus en plus de poids : la gestion de mes logiciels. Malgré le large catalogue Debian, je me retrouvais souvent à bricoler. Un wget par-ci, un binaire copié par-là, asdf, npm, la release GitHub de Neovim… Bref, plein de méthodes d’installation hétérogènes. Tout packager en .deb aurait été une solution, mais le packaging Debian est lourd à maintenir.
Autre souci, plus rare mais frustrant : deux mises à jour ont cassé des choses (ma stack PGP, puis le Bluetooth). Rien de gravissime, mais le rollback sous Debian testing, c’est à chaque fois identifier manuellement quel paquet a tout cassé. Du temps perdu juste pour pouvoir avancer.
Je n’en veux pas à Debian, c’est toujours une des meilleures distributions. Mais je me suis dit qu’on pouvait faire plus efficace.
Le meilleur des mondes
Je veux la fraîcheur d’Arch Linux et la stabilité de Debian (stable), et j’avais entendu parler d’une distribution qui promettait les deux : NixOS.

Avant de dire s’il remplit ces promesses de stabilité et de modernité, parlons un peu de NixOS.
Un système fondamentalement différent
La première chose qui m’a frappé, c’est que NixOS est un système Linux fondamentalement différent. Même en étant habitué à Linux depuis plus d’une décennie, il m’a fallu du temps pour trouver mes repères.
Premier choc : l’arborescence de fichiers. NixOS n’utilise pas l’organisation classique du File Hierarchy System. Parmi les changements majeurs, on trouve un /nix/store qui contient l’ensemble des paquets installés dans des chemins séparés et versionnés. Selon le niveau d’installation (système, utilisateur ou autre), un lien symbolique pointe vers la version actuellement utilisée. En cas de mise à jour, une nouvelle arborescence du paquet est créée dans /nix/store et le lien symbolique est mis à jour.
Rien de mieux qu’un exemple. Prenons Firefox installé au niveau système. /run/current-system représente la génération, c’est-à-dire la version actuelle du système en cours d’exécution :

Le non-respect du FHS peut théoriquement poser des soucis de compatibilité. En plusieurs mois d’utilisation, je n’ai personnellement rencontré aucun blocage.
Comme vous le voyez, au niveau système ce n’est pas vraiment pensé pour nous, humains. Au quotidien, on ne passe pas par un classique apt install, mais par des fichiers de configuration Nix. Le système fonctionne par déclaration d’état : vous voulez un nouveau logiciel, vous le déclarez dans votre configuration et vous reconstruisez le système. Vous pouvez soit basculer immédiatement sur la nouvelle version, soit attendre le prochain reboot.
environment.systemPackages = with pkgs; [
neovim
]
Ensuite un coup de : sudo nixos-rebuild switch, qui permet de reconstruire le système et de basculer dessus directement.
Comme vous l’aurez deviné, ce fonctionnement me permet aussi en une commande de revenir à la version précédente du système.

Si on passe de l’autre côté pour voir comment est géré le dépôt des packages Nix, c’est à mon avis aussi intéressant. Vous trouverez tous ces packages par ici : Github.com/NixOS/nixpkgs.
Oui, un “simple” repo Github. Votre version de système, channel dans le langage Nix est représentée par des branches. Dans le dossier pkgs, vous trouvez tous les packages disponibles. Avec pour chacun un fichier qui décrit les métadonnées, l’installation, les paramètres que vous pouvez lui passer et les tests. C’est simple et lisible, je trouve ça super agréable. Une interface web pour rechercher les packages existe aussi : search.nixos.org.
Bien sûr vous pouvez donner des paramètres aux packages pour les configurer, par exemple en activant un thème précis pour votre bureau Gnome. Typiquement pour donner des paramètres précis au thème que j’utilise, pas besoin de rebuild un paquet entier à part, suffit de faire :
paper-icon-theme
(marble-shell-theme.override {
colors = ["green"];
additionalInstallationTweaks = [ "-O" ];
})
Si vous regardez attentivement de très nombreux packages, notamment les plus importants disposent de plusieurs fichiers de tests. Ces fichiers font partie des tests faits en CI, ils sont complets et permettent de s’assurer au-delà de l’installation sans erreur du bon fonctionnement des packages automatiquement. Ce qui est un atout de taille pour la stabilité.
Au final, on se retrouve avec un système qui tient ses promesses, efficace, stable, et flexible. La joie que c’est de pouvoir mettre à jour un paramètre ou logiciel dans son code, construire et commiter tout ça pour en profiter partout. Du moins la majorité du temps.
Le langage Nix, pour le meilleur et le pire…
Car oui, tout repose sur un langage Nix, qui est très efficace, quand vous n’avez pas à faire de debug. Vous voulez faire peur à un utilisateur de Nix, envoyez-lui une stack d’erreur lors d’un build. Rien d’insurmontable, mais la majorité du temps les erreurs arrivent à ne pas être claires tout en étant très verbeuses. Je vous dis ça alors que j’étais développeur Java à la base !

Mais bon après tout on en rigole et au final, avec de la patience et un peu d’aide de notre pote Claude Code, on trouve assez rapidement la source de nos erreurs.
Une partie de la complexité peut aussi venir de l’organisation de vos fichiers Nix. Car rapidement, vous allez devoir structurer tout ça pour ne pas vous perdre et pouvoir réutiliser une bonne partie. Par exemple, dans mon cas j’ai trois PCs, deux perso et mon PC pro. Donc plusieurs bouts de système qui sont communs, notamment mon installation NeoVim.
Et cette organisation de fichiers, c’est con, mais j’ai mis du temps à m’en sortir. Quand on part de rien, je trouve ça un peu complexe de réussir à s’organiser pour faire quelque chose qui ne va pas vous cramer les yeux.
Pour tout vous dire, le plus efficace que j’ai trouvé est de consulter des dépôts Github de personnes qui ont fait leurs configurations proprement, de les lire, les comprendre et poser des questions.
Si je voulais chipoter, je dirais que nommer son système Nix, le gestionnaire de paquets Nix et le langage Nix, ce n’est pas exactement un cadeau pour les débutants. Un peu comme l’époque soviétique où tout projet spatial s’appelait Spoutnik.
Voilà pour les quelques défauts, qui sont surtout problématiques quand on découvre le système. Rien d’insurmontable, mais faut clairement se battre un peu avant de se sentir à l’aise sur le système.
Flakes, le langage Nix sous stéroïdes
Justement, un outil aide grandement à structurer votre code Nix : les Flakes.
Si vous ne connaissez pas, vous devez vous dire : « c’est quoi encore ce truc ». Donc je vais essayer de vulgariser. Dans Nix en général, vous utilisez des fichiers .nix qui sont juste des instructions Nix que vous exécutez. Mais cela pose pas mal de soucis, notamment le fait que ce n’est pas hiérarchisé et que les dépendances ne sont pas ’lock’. Donc si demain vous passez votre nix à votre collègue, si son Nix n’est pas dans le même channel que vous, vous n’aurez pas la même version.
Dans un système où on cherche au maximum à faire du reproductible et du structuré, c’est clairement un problème. C’est là que Flake apparaît pour nous sauver. Ça va être votre point d’entrée unique dans le dépôt.
Flake prend en “inputs” des dépendances, par exemple nixpkgs dans un channel défini, et en “outputs” on va définir ce que produit votre projet, par exemple une configuration NixOS.
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }: {
nixosConfigurations.mon-pc = nixpkgs.lib.nixosSystem {
# ...
};
};
}
À noter que cette fonctionnalité est expérimentale à l’heure où j’écris ces lignes, mais largement utilisée.
L’écosystème : Disko et Home manager
Disko
À l’installation de NixOS la première fois, on se retrouve face à toutes les étapes ennuyeuses : choisir un nom, créer son user, et le plus chiant, faire ses partitions. C’est là qu’apparaît Disko, une solution déclarative pour gérer ses disques et partitions.
Vous allez pouvoir y définir vos points de montage, vos volumes, le chiffrement du disque, bref tout ce qu’on attend de la gestion de disque.
Dans mon cas avec un SSD et le tout sous LUKS avec des subvolumes btrfs ça donne ça :
{
disko.devices = {
disk = {
nvme0n1 = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
label = "boot";
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "defaults" ];
};
};
luks = {
size = "100%";
label = "luks";
content = {
type = "luks";
name = "cryptroot";
extraOpenArgs = [
"--allow-discards"
"--perf-no_read_workqueue"
"--perf-no_write_workqueue"
];
content = {
type = "btrfs";
extraArgs = [
"-L"
"nixos"
"-f"
];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"subvol=root"
"compress=zstd"
"noatime"
];
};
Fichier complet : Github.com/DamyrFr/nixos-laptops-config.
Home manager
Avec Nix on a installé des logiciels, configuré notre système c’était sympa. On a formaté nos disques, c’était marrant, mais comment on gère nos configurations et dotfiles ?
Là encore on a un outil magique pour ça, Home Manager. On va déclarer dans du Nix les paramètres à configurer dans nos dotfiles. J’avoue qu’avoir tout dans un même format ça fait rêver.
Ce qui fait que pour Git par exemple, plutôt que de push un dotfile .gitconfig vous allez pouvoir faire :
programs.git = {
enable = true;
userName = "Amy Tryn";
userEmail = "amy@service.com";
extraConfig.push.autoSetupRemote = true;
};
C’est bien tout ça, mais il y a un mais : je ne l’ai pas mis pour tous mes softs. Je pense notamment à NeoVim. Tout simplement car en cas de configuration complexe on ajoute rapidement une couche d’abstraction qui crée bien plus de problèmes qu’elle n’en résout.
Par contre, sur des programmes comme Git, ça permet aussi de variabiliser des valeurs comme userName, pour la changer en fonction du host automatiquement. Et ça c’est vraiment beau !
Ma configuration et son organisation
Si ça vous intéresse de voir ce que donne ma configuration, elle est publique : Github.com/DamyrFr/nixos-laptops-config.
Mais voyons ensemble comment elle est organisée.
nixos-config/
├── flake.nix
├── flake.lock
├── hosts/
│ ├── dust/
│ ├── pro/
│ └── ghost/
└── modules/
├── core/
├── desktop/
├── pro/
└── home/
On a à la base du dépôt 2 dossiers importants :
- Hosts, qui va contenir tous les hosts que je gère dans ce dépôt. Dans mon cas 3 ordinateurs (un pro et 2 perso)
- Modules, dossier bien plus complet qui va contenir mes configurations en .nix découpées en 4 “blocs” indépendants.
À la racine, on retrouve aussi le fameux flake.nix ! On en a déjà parlé, celui-ci va prendre en input toutes mes dépendances, que vous connaissez du coup. À savoir, nixpkgs pour les packages de base, home-manager, disko. Ça c’est pour les dépendances.
À partir de là, on passe au cœur de la génération des configurations NixOS. Pour chaque host, je définis des arguments :
- Mes variables, qui vont ajuster les configurations et installations déclarées dans les modules.
- Les modules à déployer sur la machine
- Les configurations de plugins comme Home Manager
Et pour déployer le bon host sur la bonne machine il me suffit de faire : sudo nixos-rebuild switch --flake ~/nixos-config#${HOSTNAME} et ça va reconstruire mon OS et switch directement dessus.
J’en ai même fait un super alias :
nixupgrade = "sudo nixos-rebuild switch --flake ~/nixos-config#`hostname`";
Je laisse les plus curieux voir plus en détail la configuration.
Bref, pari réussi ?

Je dois vous dire que de base, je l’ai juste installé sur un vieil ordinateur portable, pour tester pour le fun. Je suis plutôt routinier quand il s’agit de ma machine, j’ai mes habitudes et je mets du temps à les changer. Donc, je ne pensais pas accrocher au point d’abandonner mes habitues !
Cette première installation c’était il y a 4 mois, déjà, aujourd’hui j’ai migré tous mes ordinateurs sous NixOS. Autant vous dire que le pari est plus que réussi. C’est sûrement pas parfait, la courbe d’apprentissage est très ardue au départ, je trouve. Mais ça marche, j’ai les mises à jour en automatique, je ne le ressens pas. J’ai peu, voire pas de retards sur les sorties des nouvelles versions de mes logiciels favoris. Sur les projets open source c’est souvent un des premiers systèmes supportés.
Surtout, j’ai cette impression, d’avoir un système et un fonctionnement homogène. Fini les configurations Ansible qui appellent un exec shell, qui lui-même va exec un bash. Ici, l’approche est logique, même si parfois cette logique et cette syntaxe me fatiguent, l’ensemble est cohérent.
Donc, je conclurai seulement par un : “I use Nix by the way”
