Nix Store : pourquoi ces hashs qui paraissent incompréhensibles sont en fait très malins
Ces noms obscurs dans /nix/store : décryptage complet
Tu les as déjà vus. Ces noms de répertoire intimidants qui traînent dans /nix/store, comme si quelqu'un avait passé un nom de package dans un mixeur cryptographique :
/nix/store/s0psayl7zvkvwdcqc8fy1sbv8rlf1yq8-bash-5.3p9
La partie lisible, c'est obvious — bash-5.3p9 te dit exactement ce qu'il y a dedans. Mais ces 32 caractères avant le tiret ? C'est là que réside le mystère. Et вот l'affaire : la plupart des explications que tu trouveras sont incomplètes.
L'explication classique (et fausse)
« Le hash vient des entrées » — c'est ce que la plupart des gens vont te dire. Ils n'ont pas tort, obviously, mais ils manquent une nuance cruciale. La vraie question, c'est : quelles entrées ? Est-ce qu'on hash les fichiers sources que t'as écrits ? La recette de build que Nix génère ? Les octets produits par le build ? Les dépendances ?
La réponse honnête : ça dépend.
Deux mécanismes de nommage, un seul répertoire
En vrai, Nix utilise deux mécanismes de nommage pour les chemins du store, et les deux cohabitent joyeusement dans /nix/store. C'est en les confondant que commence toute la confusion.
Input-Addressed : les noms avant le build
Pour la plupart des builds de packages, Nix fonctionne comme un architecte qui vérifie des plans. Quand tu écris une expression .nix, Nix l'évalue en une dérivation — une spécification concrète de ce qu'il faut build, incluant :
- Le script de build
- Les arguments de build
- Les variables d'environnement
- Les sorties déclarées
- Les dépendances
Avec cette recette en main, Nix peut calculer un identifiant unique avant même que le build ne démarre. Les binaires finis n'existent pas encore, mais Nix sait déjà comment les appeler.
C'est pour ça qu'éditer une expression Nix ne change pas toujours le chemin du store. Si tes modifications n'affectent pas la recette de build sous-jacente, Nix produit la même identité. Deux expressions différentes peuvent évaluer vers des recettes identiques, donc elles partagent le même chemin. Nix nomme ce qu'il va build, pas la façon dont ton code est écrit.
Content-Addressed : les noms来自 les octets
Nix peut aussi nommer les objets du store directement depuis leur contenu. Quand tu fais nix store add, tu donnes à Nix quelque chose qui existe déjà, et il hash les octets immédiatement. Pas d'évaluation, pas de recette — juste le contenu.
Ici, le chemin est déterminé par ce qui est vraiment dans le fichier. Change un seul octet, et le hash change.
Pourquoi cette distinction compte
Comprendre ces deux mécanismes de nommage rend plusieurs comportements de Nix soudain évidents :
Prédire les changements de chemin. Si tu te demandes « éditer X va-t-il changer le chemin du store ? », pose-toi la question : est-ce que X change la recette de build ou le contenu réel ? Éditer un commentaire dans une expression Nix ? Probablement pas de nouveau chemin. Changer une version de dépendance ? Nouveau chemin garanti.
Comprendre les builds qui cohabitent. Pourquoi un vieux résultat de build peut coexister avec un nouveau dans le store ? Parce qu'ils ont des identités différentes. Nix n'écrase pas — il n'en a simplement pas besoin.
La réutilisation des caches prend tout son sens. Un cache binaire peut servir un chemin pré-built en toute confiance parce que le nom identifie uniquelement les entrées du build. Même nom signifie même contenu, garanti.
Plus qu'un simple nom
Un chemin du store n'est jamais vraiment seul. Les packages built référencent d'autres chemins du store (bibliothèques dynamiques, interpréteurs, assets partagés), et Nix suit ces relations sous forme de graphe.
Ce n'est pas de la simple métadonnée — c'est une carte complète des dépendances. Depuis n'importe quel chemin, tu peux tracer sa closure : tout ce qui doit voyager avec lui pour fonctionner sur une autre machine. C'est comme ça que fonctionne nix-copy-closure, et pourquoi les déploiements Nix sont fiables.
La même base de données permet à Nix de vérifier l'intégrité. Il peut vérifier si les octets sur le disque correspondent toujours à ce qui a été enregistré lors de la création du chemin. Les chemins du store ne sont pas des noms de répertoire opaques — ce sont des identités requêtables avec une piste d'audit complète.
Le mot de la fin
Ces hash cryptiques ne sont pas arbitraires. Ils sont le résultat d'un choix de conception délibéré : Nix nomme les dérivations par leurs entrées et les contenus par leurs octets. Cette double approche est ce qui rend Nix reproductible, vérifiable, et surprenamment prévisible une fois que tu comprends.
Donc la prochaine fois que tu vois un chemin du store, pas de panique. Lis de droite à gauche — c'est la partie humaine. Le hash à gauche, c'est juste la façon dont Nix fait une promesse : ce nom signifie ce build, et rien d'autre.
Prêt à creuser plus loin ? Que tu déploies des containers, gères de l'infrastructure, ou que tu sois juste curieux des builds reproductibles, comprendre les entrailles de ton système paie toujours. Chez NameOcean, on croit que les meilleurs développeurs sont ceux qui comprennent ce qui se passe vraiment sous le capot — pas juste quelles commandes exécuter.
Bon build !