Aller au contenu
Administration Linux medium

Écrire une première configuration NixOS

15 min de lecture

Un fichier configuration.nix est une expression Nix qui déclare l’état complet d’un système NixOS. Vous ne lancez pas de commandes pour installer des paquets ou activer des services — vous décrivez ce que vous voulez, et nixos-rebuild switch calcule exactement ce qu’il faut faire. Maîtriser configuration.nix, c’est maîtriser la couche qui transforme le langage Nix (attrsets, fonctions, options) en système vivant. Ce guide montre comment franchir le saut entre « je connais les attrsets » et « j’ai une configuration système qui fonctionne ».

  • Lire la structure générale d’un fichier Nix : expression, arguments { config, pkgs, ... }:, bloc de sortie
  • Comprendre l’anatomie d’un configuration.nix minimal section par section
  • Distinguer un paquet (pkgs.xxx) d’une option NixOS (services.xxx.enable)
  • Trouver la bonne option dans la documentation NixOS avec search.nixos.org et nixos-option
  • Écrire une configuration concrète : paquets, SSH sécurisé, utilisateur admin
  • Appliquer les changements avec nixos-rebuild switch sans interrompre le service
  • Modulariser en fichiers séparés avec imports

Dès que vous travaillez sur un système NixOS — en VM de test, en serveur de production ou en homelab — configuration.nix est le fichier central. Savoir le lire et le modifier devient indispensable pour :

  • personnaliser un serveur NixOS installé depuis une image ou un template cloud,
  • reproduire un environnement identique sur plusieurs machines depuis un dépôt Git,
  • activer un service (SSH, Docker, Nginx) sans chercher la bonne commande d’installation,
  • diagnostiquer pourquoi un service ne démarre pas après un rebuild,
  • préparer la migration vers les flakes en comprenant d’abord la configuration de base.

Ce guide s’appuie sur les bases du langage Nix (attrsets, fonctions, let, with). Si ces notions ne sont pas encore familières, commencez par ce guide.

Tout fichier .nix est une expression — une valeur calculée, pas un script. Un configuration.nix est une fonction qui reçoit des arguments et retourne un attrset d’options :

{ config, pkgs, ... }:
{
# vos options ici
}

Les trois parties essentielles :

PartieRôle
{ config, pkgs, ... }:Arguments que NixOS injecte à l’évaluation. config expose les valeurs de toute la config ; pkgs donne accès à nixpkgs. ... accepte d’autres arguments sans les nommer.
{ ... }Le corps de la fonction : un attrset dont chaque attribut est une option NixOS (networking.hostName, services.openssh.enable, etc.).
;Chaque option dans l’attrset se termine par un point-virgule — c’est la syntaxe Nix, pas du YAML.

Voici le squelette complet d’une configuration de base, commenté section par section :

{ config, pkgs, ... }:
{
# ── 1. Imports ──────────────────────────────────────────────────────────────
imports = [
./hardware-configuration.nix # généré automatiquement lors de l'installation
];
# ── 2. Bootloader ───────────────────────────────────────────────────────────
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# ── 3. Réseau ───────────────────────────────────────────────────────────────
networking.hostName = "monserveur";
networking.networkmanager.enable = true;
# ── 4. Locale et fuseau horaire ─────────────────────────────────────────────
time.timeZone = "Europe/Paris";
i18n.defaultLocale = "fr_FR.UTF-8";
# ── 5. Paquets système ──────────────────────────────────────────────────────
environment.systemPackages = with pkgs; [
git
vim
curl
wget
];
# ── 6. Services ─────────────────────────────────────────────────────────────
services.openssh.enable = true;
# ── 7. Utilisateurs ─────────────────────────────────────────────────────────
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
# ── 8. Version d'état ───────────────────────────────────────────────────────
system.stateVersion = "24.05"; # ← ne jamais modifier après l'installation
}
SectionCe qu’elle contrôleRemarque importante
importsFichiers .nix inclus dans l’évaluationhardware-configuration.nix est généré par nixos-generate-config
boot.loaderGRUB ou systemd-boot, BIOS ou UEFIDépend du mode de démarrage de votre machine
networking.*Nom d’hôte, interfaces, DNS, firewallnetworkmanager pour les postes de travail, firewall pour les serveurs
time.timeZoneFuseau horaire systèmeFormat IANA : Europe/Paris, UTC, America/New_York
environment.systemPackagesPaquets disponibles pour tous les utilisateurswith pkgs; importe le scope nixpkgs dans la liste
services.*Activation et configuration des servicesUn module NixOS par service
users.users.*Déclaration des utilisateurs et groupesChaque utilisateur est un attrset de sa propre configuration
system.stateVersionVersion NixOS au moment de l’installation initialeNe jamais modifier — gère la compatibilité des données persistantes

C’est la source de confusion la plus fréquente pour les nouveaux utilisateurs NixOS.

Paquet (pkgs.xxx)Option service (services.xxx.enable)
Ce que c’estUn logiciel à rendre disponibleUne déclaration de comportement système
Où on le placeDans environment.systemPackagesDirectement dans le corps de la config
Ce qu’il faitRend le binaire accessible dans PATHInstalle le paquet et configure et démarre le service
Exemplepkgs.nginx (juste le binaire)services.nginx.enable = true; (le tout)

Règle pratique : si un service a un module NixOS (services.xxx), utilisez-le — il gère les paquets, la configuration et l’unité systemd. N’ajoutez pas nginx dans environment.systemPackages si vous utilisez services.nginx.enable = true;.

# ✅ Correct : le module NixOS gère tout
services.nginx.enable = true;
# ❌ Redondant et source de conflits
environment.systemPackages = with pkgs; [ nginx ];
services.nginx.enable = true;

1. search.nixos.org — le moteur officiel, le plus rapide :

https://search.nixos.org/options?query=openssh

2. nixos-option — interroge les options disponibles sur le système actif :

Fenêtre de terminal
# Lister les sous-options d'un service
nixos-option services.openssh
# Obtenir valeur actuelle + description d'une option
nixos-option services.openssh.enable
# Value: true
# Default: false
# Description: Whether to enable the OpenSSH secure shell daemon.
# Declared by: <nixpkgs/nixos/modules/services/networking/ssh/sshd.nix>

3. nix repl avec nixpkgs chargé :

Fenêtre de terminal
nix repl '<nixpkgs/nixos>'
# nix-repl> :t options.services.openssh
# nix-repl> options.services.openssh.enable

Configurer un serveur NixOS avec :

  • git, vim, curl, htop disponibles en ligne de commande
  • SSH activé avec authentification par mot de passe désactivée
  • Un utilisateur admin dans le groupe wheel (accès sudo)
  • Fuseau horaire Europe/Paris
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "serveur-prod";
networking.networkmanager.enable = true;
time.timeZone = "Europe/Paris";
i18n.defaultLocale = "fr_FR.UTF-8";
environment.systemPackages = with pkgs; [
git
vim
curl
htop
];
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
users.users.admin = {
isNormalUser = true;
description = "Administrateur système";
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... votre_cle_publique"
];
};
security.sudo.wheelNeedsPassword = false;
system.stateVersion = "24.05";
}
  1. Éditer le fichier (en root ou via sudo)

    Fenêtre de terminal
    sudo vim /etc/nixos/configuration.nix
  2. Valider la configuration sans l’appliquer

    Fenêtre de terminal
    sudo nixos-rebuild dry-build
    # Construire sans rien changer au système — sortie d'erreur si syntaxe incorrecte
  3. Appliquer les changements

    Fenêtre de terminal
    sudo nixos-rebuild switch
    # Build + activation immédiate + entrée dans le bootloader
  4. Vérifier le résultat

    Fenêtre de terminal
    # Paquets disponibles ?
    which git vim curl htop
    # SSH démarré ?
    systemctl status sshd
    # Utilisateur créé ?
    id admin
ErreurSymptômeSolution
Oublier le ;error: expected ';', got ...Chaque option dans un attrset se termine par ;
Confondre [ ] et { }Erreur de type lors du buildsystemPackages attend une liste [ ], pas un attrset { }
Mettre un paquet là où une option est attendueLe service ne démarre passervices.nginx.enable = pkgs.nginx est faux — écrire = true
Modifier system.stateVersionComportement imprévisible sur les données existantesNe jamais changer after l’installation initiale
Oublier git add avant rebuildLes nouveaux fichiers importés sont ignorésgit add . avant nixos-rebuild quand la config est dans un dépôt
error: attribute 'gittt' missing
at /etc/nixos/configuration.nix:12:5:
11| environment.systemPackages = with pkgs; [
12| gittt
^
13| ];
  • attribute 'gittt' missing — le paquet n’existe pas dans nixpkgs, faute de frappe probable.
  • at …:12:5 — ligne 12, colonne 5 — le curseur est précis.
  • Correction : nix search nixpkgs git pour trouver le nom exact.

Première modularisation : diviser la configuration

Section intitulée « Première modularisation : diviser la configuration »

Dès que configuration.nix dépasse une cinquantaine de lignes, découpez-le en fichiers thématiques.

/etc/nixos/
├── configuration.nix ← entrée principale + options globales
├── hardware-configuration.nix
├── users.nix ← déclaration des utilisateurs
└── services/
└── ssh.nix ← configuration SSH
{ config, pkgs, ... }:
{
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."
];
};
}
{ config, pkgs, ... }:
{
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
}
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./users.nix
./services/ssh.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "serveur-prod";
time.timeZone = "Europe/Paris";
environment.systemPackages = with pkgs; [
git vim curl htop
];
system.stateVersion = "24.05";
}

nixos-rebuild switch évalue tous les fichiers listés dans imports comme s’ils n’en formaient qu’un seul. C’est simple et suffisant pour la majorité des configurations.

ErreurCause probableVérificationSolution
error: syntax error; manquant ou accolade non ferméeLigne indiquée dans le message d’erreurVérifier ; en fin d’option, { } équilibrés
attribute 'xxx' missingPaquet ou option inexistantenix search nixpkgs xxx ou nixos-option xxxCorriger le nom ou trouver l’option équivalente
nixos-rebuild switch bloqueBuild de dépendances volumineuxjournalctl -u nixos-rebuild en parallèleAttendre — première activation peut être longue
Failed to start sshd.serviceConfiguration SSH invalide ou port déjà utilisésystemctl status sshd + journalctl -u sshdVérifier services.openssh.settings, port 22 libre
Service absent après rebuildOption enable = false ou non déclaréenixos-option services.xxx.enableAjouter ou corriger l’option dans la config
file 'hardware-configuration.nix' not foundFichier manquant dans le chemin importéls /etc/nixos/Regénérer avec sudo nixos-generate-config
  • configuration.nix est une fonction Nix — elle reçoit config et pkgs, et retourne un attrset d’options NixOS.
  • Paquet (environment.systemPackages) et option service (services.xxx.enable) sont deux mécanismes distincts — les modules NixOS font les deux à la fois, ne doublez pas.
  • Utilisez search.nixos.org/options ou nixos-option localement pour trouver la bonne option.
  • nixos-rebuild dry-build valide sans appliquer — utilisez-le systématiquement avant switch.
  • system.stateVersion ne se modifie jamais après l’installation initiale.
  • La modularisation avec imports = [ ./fichier.nix ] est simple et efficace — découpez tôt.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn