mise, Nix et devcontainers résolvent tous le problème « ça marche sur ma machine » — ils ne sont pas d’accord sur la méthode

L'expression « ça marche sur ma machine » a hanté les équipes logicielles pendant des décennies. Une nouvelle recrue arrive, passe deux jours à configurer son environnement. Un développeur senior met à jour Python, casse trois projets. L'IC échoue à cause d'une version de bibliothèque que personne n'avait souvenir d'avoir figée. La cause racine est toujours la même : les environnements de développement sont avec état, implicites et assemblés manuellement.
En 2026, ce problème est véritablement résolu — mais « résolu » signifie trois outils concurrents avec des philosophies radicalement différentes. Comprendre les compromis est la vraie compétence.
Niveau 1 — mise : Le point de départ pragmatique
mise (anciennement rtx) est un gestionnaire de versions polyglotte écrit en Rust. Il remplace asdf tout en étant 10 à 20 fois plus rapide grâce à son noyau compilé et à la résolution parallèle des plugins. Il gère Node.js, Python, Go, Ruby, Java et des dizaines d'autres environnements d'exécution à partir d'un seul outil.
Le mécanisme principal est le fichier .mise.toml à la racine du projet :
[tools]
node = "22.3.0"
python = "3.12.4"
go = "1.22.5"
[env]
DATABASE_URL = "postgres://localhost/myapp_dev"
Exécutez mise install et il lit la configuration, télécharge les versions figées dans un cache local à adressage par contenu (~/.local/share/mise/installs/) et les active pour le répertoire courant. Pas de manipulation de liens symboliques, pas de bidouilles shell au-delà de l'ajout de mise activate dans votre profil.
La différence de performances par rapport à asdf n'est pas subtile. Installer une version de Node.js qu'asdf met 45 secondes à résoudre et installer, mise la termine en moins de 4 secondes. Pour les équipes qui basculent constamment entre des projets ayant des besoins d'exécution différents, cela se traduit par des économies de temps réelles.
Ce que mise ne fait pas : il gère les environnements d'exécution des langages, pas les bibliothèques système. Si votre projet nécessite une version spécifique de libpq, openssl ou ffmpeg, mise ne peut pas aider. Il ne peut pas non plus reproduire la version exacte de glibc sous Linux ni la chaîne d'outils Xcode exacte sous macOS. Pour la plupart des développeurs d'applications, ces lacunes n'ont pas d'importance. Pour tous les autres, lisez la suite.
Niveau 2 — Nix et Nix Flakes : Reproductibilité totale
Nix est un gestionnaire de paquets fonctionnel construit autour d'une idée : chaque paquet est une fonction pure de ses entrées. Avec les mêmes entrées, vous obtenez toujours la même sortie. Les paquets vivent dans /nix/store/ sous des chemins à adressage par contenu comme /nix/store/ybmrfz0-nodejs-22.3.0/. Deux paquets peuvent dépendre de différentes versions de la même bibliothèque sans conflit car ils vivent littéralement à des chemins différents.
nixpkgs est le dépôt de paquets : plus de 90 000 paquets, tous construits de manière reproductible, couvrant tous les grands écosystèmes de langages ainsi que les outils système, les polices, les bases de données et les compilateurs. C'est le plus grand ensemble de paquets à source unique de toutes les distributions Linux.
Nix flakes (stabilisé dans NixOS 23.11) ajoute un modèle de dépendances piloté par fichier de verrouillage à Nix lui-même. Un fichier flake.nix à la racine du projet fige le commit exact de nixpkgs et définit un devShell :
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
packages = with nixpkgs.legacyPackages.x86_64-linux; [
nodejs_22
python312
go_1_22
postgresql_16
ffmpeg
];
};
};
}
Exécutez nix develop et vous entrez dans un shell où chaque outil est exactement comme spécifié — jusqu'aux versions de la bibliothèque C. Le fichier flake.lock fige le SHA du commit de nixpkgs. Six mois plus tard, sur une machine différente, dans un pays différent, nix develop produit le même environnement.
La courbe d'apprentissage honnête : Nix a son propre langage fonctionnel (appelé aussi Nix), son propre modèle mental du fonctionnement des builds, et une documentation qui suppose une familiarité avec les concepts de programmation fonctionnelle. La plupart des développeurs mettent 1 à 2 semaines avant de se sentir à l'aise pour écrire des flakes à partir de zéro. Des outils comme devenv.sh et flake-parts réduisent cela considérablement, mais il n'y a pas de raccourci pour les concepts fondamentaux.
Le retour sur investissement est réel. Les équipes qui utilisent Nix flakes ne signalent aucun problème de « dérive d'environnement » dans les bilans post-mortem. L'IC exécute le même shell nix develop que le développement local. Les nouvelles recrues exécutent nix develop dès le premier jour et disposent d'un environnement fonctionnel en quelques minutes, pas en jours.
Niveau 3 — devcontainers : Intégration et développement cloud-first
devcontainers est une spécification ouverte (soutenue par Microsoft et utilisée dans VS Code et GitHub Codespaces) qui définit un environnement de développement comme un conteneur Docker. La configuration se trouve dans .devcontainer/devcontainer.json :
{
"name": "My Project",
"image": "mcr.microsoft.com/devcontainers/javascript-node:22",
"features": {
"ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
"ghcr.io/devcontainers/features/go:1": { "version": "1.22" }
},
"postCreateCommand": "npm install",
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
}
}
}
L'extension Remote - Containers de VS Code monte vos fichiers locaux dans le conteneur et exécute tout votre éditeur à l'intérieur — serveurs de langage, débogueurs, terminaux, tout s'exécutant dans l'environnement du conteneur. GitHub Codespaces va plus loin : cliquez sur « Open in Codespaces » et l'ensemble de l'environnement de développement s'exécute sur l'infrastructure cloud de GitHub, pas sur votre ordinateur portable.
Où les devcontainers excellent : l'intégration est véritablement en un clic. L'isolation de sécurité est réelle — le système de fichiers du conteneur est séparé de celui de l'hôte. Pour les tâches lourdes en calcul (entraînement de grands modèles, rendu vidéo, compilation de grandes bases de code C++), décharger vers Codespaces avec des machines cloud à 32 cœurs est une productivité légitime.
Où les devcontainers peinent : la surcharge de Docker est réelle sur macOS. Les performances du système de fichiers via la couche VM de Docker peuvent être 2 à 3 fois plus lentes que le natif pour les tâches intensives en E/S, comme l'exécution d'une grande suite de tests. Vous dépendez également de la connectivité réseau et du fonctionnement de Docker — ni l'un ni l'autre n'est garanti dans tous les contextes de développement.
Comment les équipes réelles combinent ces outils
Le mauvais choix est d'en sélectionner un et d'y aller à fond. Les équipes qui ont compris cela procèdent généralement par couches :
- mise pour le changement de langage au quotidien. Chaque développeur l'a. Il gère 90 % des questions « quelle version de Node/Python/Go » avec un minimum de friction. Le fichier
.mise.tomlest commité dans le dépôt. - Nix flakes pour les équipes avec des exigences au niveau système. Si vous avez besoin de versions spécifiques de bibliothèques natives, ou si vous construisez à la fois sous Linux et macOS et avez besoin d'environnements identiques,
flake.nixvaut l'investissement. Certaines équipes n'utilisent Nix que pour l'IC, obtenant la reproductibilité là où elle compte le plus. - devcontainers pour l'intégration et la parité avec l'IC. La configuration
.devcontainer/est conservée pour le premier jour des nouvelles recrues et pour l'accès à GitHub Codespaces. Elle ne remplace pas les outils de développement locaux mais fournit une sauvegarde garantie.
Un exemple concret : une équipe de 12 développeurs utilise mise localement pour le changement rapide de versions, Nix flakes dans l'IC (GitHub Actions exécute nix develop --command make test) et un devcontainer pour l'accès à Codespaces lorsque les membres de l'équipe voyagent ou sont sur des machines d'entreprise verrouillées.
Les compromis honnêtes
- mise : s'installe en 30 secondes, fonctionne partout, gère 90 % des vrais problèmes, mais ne peut pas gérer les bibliothèques système ni garantir la reproductibilité binaire en dessous du niveau de l'environnement d'exécution du langage.
- Nix : l'option la plus puissante disponible, produit des environnements véritablement reproductibles bit pour bit, couvre toutes les couches de la pile, mais nécessite un réel investissement pour l'apprentissage et peut rendre des tâches simples (ajouter une nouvelle dépendance de paquet) lourdes jusqu'à ce que les concepts s'installent.
- devcontainers : la barrière à l'entrée la plus basse pour l'intégration, natif du cloud, natif de VS Code, mais entraîne une surcharge Docker, nécessite une connectivité et peut obscurcir les détails de l'environnement d'une manière qui rend le débogage plus difficile.
Par où commencer
Si votre équipe compte moins de 5 développeurs et que la douleur est « chacun a des versions différentes de Node/Python » : installez mise aujourd'hui, commitez un .mise.toml, c'est fait. Vous résoudrez 90 % des plaintes liées à l'environnement en un après-midi.
Si votre équipe compte 10 développeurs ou plus, vous livrez sur Linux, vous avez des dépendances de bibliothèques natives et la dérive d'environnement a causé de véritables incidents de production : investissez dans Nix flakes. Prévoyez 2 à 3 semaines pour qu'un développeur devienne l'expert Nix de l'équipe. Le retour est réel.
Si votre principale difficulté est le temps d'intégration, vous travaillez intensivement avec GitHub ou vous avez besoin d'un isolement sécurisé pour les sous-traitants : les devcontainers sont le bon levier. Ils se combinent bien avec mise et Nix — vous pouvez exécuter mise à l'intérieur d'un devcontainer, ou construire votre image devcontainer à partir d'une dérivation Nix.
Le problème « ça marche sur ma machine » est résolu. La question restante est de savoir quelle solution correspond aux contraintes réelles de votre équipe — et si vous êtes prêt à payer les coûts d'apprentissage que les options les plus puissantes nécessitent.