Aller au contenu

NixOS dans WSL : environnement complet

Mise à jour :

Ce guide explique comment transformer WSL en une distribution NixOS complète, prête pour le travail DevOps au quotidien.

Aucune connaissance préalable de Nix n’est requise pour suivre ce tutoriel. Cependant, si vous souhaitez comprendre les concepts sous-jacents (Nix Store, générations, configuration déclarative), je vous recommande de consulter d’abord mon guide d’introduction à Nix.

Pourquoi NixOS dans WSL ?

WSL2 offre un environnement Linux puissant, mais souffre de limitations :

  • Configurations difficiles à reproduire d’une machine à l’autre
  • Dépendance à Docker Desktop (licence payante en entreprise)
  • Environnement qui se dégrade au fil des installations

NixOS résout ces problèmes :

  • Déclaratif : tout le système se définit dans des fichiers de configuration
  • Reproductible : même configuration = même environnement, garanti
  • Rollback instantané : retour arrière en une commande si quelque chose casse
  • Isolation par projet : chaque projet peut avoir ses propres versions d’outils

Préparatifs

Si vous n’avez pas encore WSL, vous pouvez consulter mon guide d’installation : Installer WSL sur Windows 11.

Je m’assure d’avoir la dernière version de WSL :

Terminal window
# Mise à jour WSL
wsl --install --no-distribution
wsl --update

Cela garantit que j’ai la dernière version de WSL avec le support de systemd.

Installer NixOS dans WSL

Téléchargement de NixOS-WSL

Je télécharge le fichier nixos.wsl depuis la dernière release : 👉 https://github.com/nix-community/NixOS-WSL/releases/latest

Avec WSL 2.4.4 ou plus récent, je double-clique simplement sur le fichier nixos.wsl téléchargé pour lancer l’installation.

Post-installation

Je suis maintenant dans un système NixOS minimal.

Terminal window
La distribution a été installée. Il peut être lancé via 'wsl.exe -d NixOS'
Lancement : NixOS...
Welcome to your new NixOS-WSL system!
Please run `sudo nix-channel --update` and `sudo nixos-rebuild switch` now, to ensure you're running the latest NixOS and NixOS-WSL versions.
If you run into issues, please report them on our Github page at https://github.com/nix-community/NixOS-WSL or come talk to us on Matrix at #wsl:nixos.org.
❄️ Enjoy NixOS-WSL! ❄️
Note: this message will disappear after you rebuild your system. If you want to see it again, run `nixos-wsl-welcome`.
[nixos@nixos:/mnt/c/wsl/nixos]$

Réaliser les mises à jour initiales :

Terminal window
# Mise à jour des canaux Nix et reconstruction du système
sudo nix-channel --update
sudo nixos-rebuild switch # Cette commande peut prendre du temps

Pour rappel, NixOS est une distribution immuable, tout est défini par configuration. Je vais donc personnaliser mon système en éditant des fichiers de configuration. Pour appliquer les changements, j’utiliserai la commande nixos-rebuild switch. Cette commande reconstruit le système à partir des fichiers de configuration et l’applique (pas besoin de reboot).

On peut à tout moment revenir à une version antérieure si besoin avec la commande nixos-rebuild switch --rollback.

Pour obtenir la liste des versions disponibles, on peut utiliser :

Terminal window
# Liste des générations NixOS disponibles
sudo nix-env -p /nix/var/nix/profiles/system --list-generations

Configuration de NixOS : deux approches

Il existe deux façons de configurer NixOS :

  1. Approche simple : Modifier directement /etc/nixos/configuration.nix
  2. Approche avancée : Utiliser un dépôt Git avec Nix flakes (recommandé pour la reproductibilité)

Je commence par l’approche simple pour comprendre les bases, puis je passe aux flakes.

Approche simple : modification de configuration.nix

Ajouter des paquets

Pour installer des outils, j’ajoute dans configuration.nix :

{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
git
vim
curl
jq
htop
];
}

Puis sudo nixos-rebuild switch.

Activation de Docker

Par exemple, pour activer Docker, j’édite la configuration système :

Terminal window
# Édition de la configuration NixOS
sudo nano /etc/nixos/configuration.nix

J’ajoute dans le bloc de configuration :

{ config, pkgs, ... }:
{
# ... autres options existantes ...
# Activation de Docker
virtualisation.docker.enable = true;
# Ajouter mon utilisateur au groupe docker
users.users.nixos.extraGroups = [ "docker" ];
}

J’applique les changements :

Terminal window
# Reconstruction du système
sudo nixos-rebuild switch
# Se déconnecter/reconnecter pour que le groupe docker soit pris en compte

Je peux maintenant utiliser Docker :

Terminal window
docker run hello-world

Tester un outil sans l’installer globalement

Pour tester un outil sans l’installer globalement, j’utilise nix-shell :

Terminal window
# Tester Terraform sans l'installer globalement
nix-shell -p htop"

A partir de là, l’invite de commande change, indiquant que je suis dans un shell temporaire avec htop disponible. Pour quitter, je tape exit.

Terminal window
[nix-shell:/mnt/c/wsl/nixos]$ htop
# (htop s'exécute ici)
[nix-shell:/mnt/c/wsl/nixos]$ exit

Approche avancée : dépôt Git avec flakes

Cette approche permet de :

  • Versionner toute la configuration dans Git
  • Partager/reproduire l’environnement sur une autre machine
  • Organiser la configuration en modules réutilisables

Étape 1 : Créer le dépôt de configuration

Terminal window
# Création du dossier de configuration
mkdir -p ~/nixos-config
cd ~/nixos-config
nix-shell -p git
git init
git config user.name "Mon Nom"
git config user.email "mon.email@example.com"
git branch -M main

Créez votre dépôt Git vide sur GitHub ou autre, puis ajoutez la remote :

Terminal window
git remote add origin git@github.com:username/nixos-config.git
git config push.default current

Si cette un dépôt privé, pensez à configurer une clé SSH pour l’accès.

Terminal window
ssh-keygen -t ed25519 -C "mon.email@example.com"
cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1WilJ...... mon.email@example.com

Copier cette clé publique dans les paramètres SSH de votre compte GitHub.

Étape 2 : Structure du dépôt

Je crée cette structure :

nixos-config/
├── flake.nix # Point d'entrée principal
├── hosts/
│ └── wsl.nix # Configuration spécifique WSL
└── modules/
├── docker.nix # Module Docker
└── tools.nix # Outils CLI

Voilà les commandes pour créer cette structure :

Terminal window
mkdir -p hosts modules

Étape 3 : Créer flake.nix

Terminal window
# Création du fichier flake.nix
cat > ~/nixos-config/flake.nix << 'EOF'
{
description = "Ma configuration NixOS-WSL";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixos-wsl.url = "github:nix-community/NixOS-WSL";
nixos-wsl.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, nixos-wsl, ... }:
{
nixosConfigurations.wsl = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
nixos-wsl.nixosModules.wsl
./hosts/wsl.nix
];
};
};
}
EOF

Étape 4 : Créer la configuration WSL

Terminal window
# Création de la configuration WSL
cat > ~/nixos-config/hosts/wsl.nix << 'EOF'
{ config, pkgs, ... }:
{
# Configuration WSL
wsl = {
enable = true;
defaultUser = "nixos";
};
# Activation des flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Paquets système
environment.systemPackages = with pkgs; [
git vim curl jq htop
];
# Docker
virtualisation.docker.enable = true;
users.users.nixos.extraGroups = [ "docker" ];
# Timezone
time.timeZone = "Europe/Paris";
system.stateVersion = "25.05"; # Mettre à jour selon la version actuelle de NixOS
}
EOF

Étape 5 : Appliquer la configuration flake

Terminal window
# Premier commit (obligatoire pour que flake fonctionne)
git add .
git commit -m "Configuration initiale NixOS-WSL"
git push -u origin HEAD:main
# Application de la configuration
sudo nixos-rebuild switch --flake .#wsl

Attention: Ici, nous avons activé docker, il faut se déconnecter/reconnecter pour que le groupe docker soit pris en compte.

Étape 6 : Modifications futures

Pour ajouter des paquets ou modifier la configuration, j’édite les fichiers dans hosts/wsl.nix ou crée des modules dans modules/, puis j’applique avec nixos-rebuild --flake .#wsl.

Par exemple, nous allons ajouter le package python 3.12 :

Terminal window
# Édition de la configuration WSL pour ajouter Python
nano ~/nixos-config/hosts/wsl.nix

Jajoute python312 dans environment.systemPackages :

environment.systemPackages = with pkgs; [
git vim curl jq htop python312
];

Pour modifier ma configuration :

Terminal window
# 2. Versionner les changements
git add .
git commit -m "chore: Ajout de nouveaux paquets"
# 3. Appliquer
sudo nixos-rebuild switch --flake .#wsl

Étape 7 : Organiser en modules réutilisables

Une fois à l’aise avec les bases, je peux organiser ma configuration en modules.

Module Docker avancé

Terminal window
mkdir -p ~/nixos-config/modules
cat > ~/nixos-config/modules/docker.nix << 'EOF'
# Module Docker avec configuration optimisée
{ config, pkgs, ... }:
{
virtualisation.docker = {
enable = true;
enableOnBoot = true;
autoPrune.enable = true;
};
}
EOF

Module outils CLI

Terminal window
cat > ~/nixos-config/modules/tools.nix << 'EOF'
# Outils CLI pour le développement
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
# Navigation et recherche
fzf zoxide lsd ripgrep fd jq yq
# Réseau
curl wget htop
# Git
git gh lazygit
];
}
EOF

Module Zsh avec Oh My Zsh

Terminal window
cat > ~/nixos-config/modules/zsh.nix << 'EOF'
# Configuration Zsh avec Oh My Zsh
{ config, pkgs, ... }:
{
# Définir Zsh comme shell par défaut
users.defaultUserShell = pkgs.zsh;
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestions.enable = true;
syntaxHighlighting.enable = true;
# Oh My Zsh
ohMyZsh = {
enable = true;
theme = "robbyrussell"; # ou "agnoster", "powerlevel10k", etc.
plugins = [
"git"
"docker"
"kubectl"
"fzf"
"zoxide"
"history"
"sudo"
];
};
# Aliases personnalisés
shellAliases = {
ll = "lsd -la";
ls = "lsd";
cat = "bat";
k = "kubectl";
update = "sudo nixos-rebuild switch --flake ~/nixos-config#wsl";
gc = "sudo nix-collect-garbage -d";
};
};
# Paquets requis pour les plugins Oh My Zsh
environment.systemPackages = with pkgs; [
bat # cat amélioré
eza # ls moderne (alternative à lsd)
starship # prompt alternatif (optionnel)
fzf # requis pour le plugin fzf
zoxide # requis pour le plugin zoxide
kubectl # requis pour le plugin kubectl
];
}
EOF

Utiliser les modules dans wsl.nix

Je modifie hosts/wsl.nix pour importer les modules et supprimer les déclarations redondantes (Docker et paquets sont maintenant dans les modules) :

Terminal window
cat > ~/nixos-config/hosts/wsl.nix << 'EOF'
{ config, pkgs, ... }:
{
imports = [
../modules/docker.nix
../modules/tools.nix
../modules/zsh.nix
];
wsl = {
enable = true;
defaultUser = "nixos";
};
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Docker est activé dans modules/docker.nix
# On garde juste l'ajout au groupe
users.users.nixos.extraGroups = [ "docker" ];
time.timeZone = "Europe/Paris";
system.stateVersion = "25.05";
}
EOF

Puis j’applique :

Terminal window
cd ~/nixos-config
git add .
git commit -m "chore: Ajout modules Docker, outils et Zsh"
git push
sudo nixos-rebuild switch --flake .#wsl

Après le rebuild, fermer et rouvrir le terminal pour que Zsh soit actif.

Étape 8 : Compatibilité VS Code Remote (nix-ld)

Par défaut, NixOS ne peut pas exécuter les binaires compilés pour les distributions Linux classiques (Debian, Ubuntu…). VS Code Remote télécharge son propre serveur Node.js qui échoue avec l’erreur :

Could not start dynamically linked executable: .vscode-server/.../node
NixOS cannot run dynamically linked executables intended for generic linux

La solution est d’activer nix-ld, qui fournit un linker dynamique compatible :

Terminal window
cat > ~/nixos-config/modules/vscode.nix << 'EOF'
# Compatibilité VS Code Remote et binaires dynamiques
{ config, pkgs, ... }:
{
# nix-ld permet d'exécuter des binaires non-Nix (VS Code, etc.)
programs.nix-ld = {
enable = true;
# Bibliothèques communes requises par VS Code et autres outils
libraries = with pkgs; [
stdenv.cc.cc.lib
zlib
openssl
curl
glib
util-linux
icu
libunwind
libuuid
# Pour VS Code
xorg.libX11
xorg.libXcursor
xorg.libXrandr
];
};
}
EOF

J’ajoute le module dans wsl.nix :

Terminal window
cat > ~/nixos-config/hosts/wsl.nix << 'EOF'
{ config, pkgs, ... }:
{
imports = [
../modules/docker.nix
../modules/tools.nix
../modules/zsh.nix
../modules/vscode.nix
];
wsl = {
enable = true;
defaultUser = "nixos";
};
nix.settings.experimental-features = [ "nix-command" "flakes" ];
users.users.nixos.extraGroups = [ "docker" ];
time.timeZone = "Europe/Paris";
system.stateVersion = "25.05";
}
EOF

J’applique et je redémarre WSL :

Terminal window
cd ~/nixos-config
git add .
git commit -m "feat: Ajout nix-ld pour VS Code Remote"
git push
sudo nixos-rebuild switch --flake .#wsl

Puis dans PowerShell :

Terminal window
# Redémarrer WSL pour prendre en compte nix-ld
wsl --shutdown

Relancer VS Code et ouvrir un dossier WSL — le serveur devrait maintenant démarrer correctement.

Conclusion

Ce guide met en place un environnement DevOps complet :

  • NixOS dans WSL : distribution reproductible et immuable
  • Docker natif : conteneurs sans Docker Desktop
  • Zsh + Oh My Zsh : shell productif avec autocomplétion et plugins
  • VS Code Remote : développement fluide grâce à nix-ld
  • Configuration modulaire : dépôt Git versionné et partageable

L’ensemble forme une station de travail DevOps portable : je peux cloner mon dépôt nixos-config sur une nouvelle machine et retrouver exactement le même environnement en une commande.

Pistes à explorer

Ce guide pose les bases d’un environnement NixOS-WSL fonctionnel. Voici quelques pistes pour aller plus loin :

  • Home Manager : gérer la configuration utilisateur (dotfiles, programmes) de façon déclarative, séparément du système
  • Workspace chiffré LUKS : créer un volume chiffré portable pour les secrets et projets sensibles
  • QEMU/KVM : activer la virtualisation imbriquée pour tester des VMs directement dans WSL
  • Cachix : accélérer les builds en utilisant un cache binaire partagé
  • Sops-nix : gérer les secrets chiffrés directement dans la configuration NixOS

Plus d’infos

Documentation officielle

Exemples de configurations

Ces dépôts publics montrent comment d’autres utilisateurs structurent leur configuration NixOS-WSL :

Communauté

  • NixOS Discourse : forum officiel, idéal pour les questions
  • NixOS Wiki : wiki communautaire avec de nombreux exemples
  • r/NixOS : subreddit actif
  • Matrix : #nixos:nixos.org et #wsl:nixos.org pour le chat en temps réel