ITSkillsCenter
Business Digital

nixos-rebuild remote : déployer NixOS sur un serveur distant

9 min de lecture

📍 Guide principal : NixOS pour développeurs et serveurs : reproductibilité totale en 2026
Ce tutoriel suppose que vous avez déjà un flake fonctionnel pour votre poste de travail (cf. Flakes : essentiels et premier projet reproductible) et un serveur cible accessible en SSH avec NixOS installé.

Le déploiement NixOS, version git push pour serveurs

L’approche classique du déploiement Linux est laborieuse : se connecter en SSH, lancer apt update, installer un paquet, éditer un fichier de config dans /etc, redémarrer un service, espérer que ça marche. Quand on gère cinq serveurs, on écrit des playbooks Ansible. Quand on en gère trente, on s’arrache les cheveux quand un serveur a dérivé silencieusement parce qu’un junior a fait juste un apt install en urgence il y a six mois.

NixOS résout ce problème par nixos-rebuild --target-host. Vous décrivez chaque serveur dans un flake, vous lancez la commande sur votre poste, elle compile la nouvelle configuration localement (ou sur le serveur lui-même selon vos contraintes), elle copie les chemins du store par SSH, elle active la nouvelle génération. Si quelque chose casse, nixos-rebuild switch --rollback --target-host remet la génération précédente. Aucun fichier n’est modifié sur place — le serveur saute d’un état à l’autre, atomiquement.

Ce tutoriel monte un déploiement complet : un serveur distant vps01.exemple.fr qui sert de host, un flake local qui le décrit, et la pratique du déploiement avec une bande passante limitée.

Prérequis

  • Un serveur cible avec NixOS 25.11 installé (suivez le tutoriel d’installation sur le serveur, ou utilisez une image NixOS chez votre fournisseur cloud).
  • Accès SSH root au serveur, ou un utilisateur avec sudo sans mot de passe.
  • Une clé SSH déposée sur le serveur (~/.ssh/authorized_keys).
  • Un flake local fonctionnel sur votre poste de travail.

Étape 1 — Décrire le serveur dans votre flake

Dans le flake qui sert votre infra (différent de celui de vos dotfiles ou de vos projets), ajoutez une nixosConfigurations par serveur. Voici la structure type pour un VPS Hetzner ou OVH :

{
  description = "Infra : serveurs NixOS";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";

  outputs = { self, nixpkgs }: {
    nixosConfigurations.vps01 = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ./hosts/vps01/configuration.nix
        ./hosts/vps01/hardware-configuration.nix
        ./modules/common.nix
      ];
    };
  };
}

Le fichier hosts/vps01/hardware-configuration.nix est généré par nixos-generate-config sur le serveur — copiez-le depuis le serveur vers votre dépôt après l’installation initiale. configuration.nix contient les options spécifiques (hostname, IP, users), common.nix contient les options partagées entre tous vos serveurs (firewall, ssh hardening, monitoring).

Étape 2 — La configuration minimale d’un serveur

Voici un hosts/vps01/configuration.nix typique pour un serveur web :

{ config, pkgs, lib, ... }:
{
  imports = [];

  boot.loader.grub.enable = true;
  boot.loader.grub.device = "/dev/sda";

  networking.hostName = "vps01";
  networking.useDHCP = true;
  networking.firewall.enable = true;
  networking.firewall.allowedTCPPorts = [ 22 80 443 ];

  time.timeZone = "Europe/Paris";

  users.users.deploy = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3Nz... alice@laptop"
    ];
  };

  services.openssh = {
    enable = true;
    settings.PasswordAuthentication = false;
    settings.PermitRootLogin = "prohibit-password";
  };

  security.sudo.wheelNeedsPassword = false;

  nix.settings.experimental-features = [ "nix-command" "flakes" ];
  nix.gc.automatic = true;
  nix.gc.options = "--delete-older-than 30d";

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

  system.stateVersion = "25.11";
}

L’utilisateur deploy avec sudo sans mot de passe est ce qui permettra à nixos-rebuild de propager la nouvelle config sans interaction. Sa clé SSH est listée explicitement — pas de ssh-copy-id manuel, tout est dans le flake.

Étape 3 — Le premier rebuild distant

Depuis votre poste de travail, à la racine du flake :

nixos-rebuild switch --flake .#vps01 \
  --target-host deploy@vps01.exemple.fr \
  --use-remote-sudo

La commande compile la configuration localement (sur votre poste), copie les chemins du store nécessaires vers le serveur via SSH, active la nouvelle génération à distance. --use-remote-sudo indique que la commande sudo doit s’exécuter côté serveur après le transfert. Le premier rebuild peut prendre du temps : il faut transférer toutes les dépendances. Les rebuilds suivants ne transfèrent que les diffs.

Si la commande échoue avec une erreur SSH, vérifiez que votre clé est bien dans ~/.ssh/authorized_keys du serveur, et que ssh deploy@vps01.exemple.fr "sudo whoami" retourne « root » sans demander de mot de passe.

Étape 4 — Compiler sur le serveur plutôt que localement

Si votre poste a une connexion lente et que le serveur a une bonne bande passante, l’inverse fait gagner du temps. --build-host compile sur la machine cible :

nixos-rebuild switch --flake .#vps01 \
  --target-host deploy@vps01.exemple.fr \
  --build-host deploy@vps01.exemple.fr \
  --use-remote-sudo

Maintenant, votre poste ne sert plus qu’à orchestrer : il évalue le flake (rapide), envoie l’expression Nix au serveur, le serveur télécharge depuis cache.nixos.org à pleine vitesse et compile localement. Pour un serveur avec 1 Gbps de bande passante face à votre 4G mobile, le gain est massif.

Étape 5 — Tester sans appliquer : build et test

Avant un switch en production, deux variantes prudentes. nixos-rebuild build compile sans activer — utile pour vérifier que la config évalue sans erreur. nixos-rebuild test --target-host active la nouvelle génération sans la rendre persistante ; si le serveur reboote, il revient sur l’ancienne génération. C’est le filet de sécurité ultime pour les changements risqués.

# Vérifier sans déployer
nixos-rebuild build --flake .#vps01

# Activer mais pas persistant (rollback automatique au reboot)
nixos-rebuild test --flake .#vps01 \
  --target-host deploy@vps01.exemple.fr \
  --use-remote-sudo

# Si tout marche, switch persistant
nixos-rebuild switch --flake .#vps01 \
  --target-host deploy@vps01.exemple.fr \
  --use-remote-sudo

Cette séquence est la pratique standard pour un déploiement en production sensible : on teste, on observe, on persiste seulement quand on est sûr.

Étape 6 — Rollback distant

Si le déploiement casse une fonctionnalité, deux options. Rollback distant :

nixos-rebuild switch --rollback \
  --target-host deploy@vps01.exemple.fr \
  --use-remote-sudo

Le serveur revient à la génération précédente. Vous corrigez sur votre poste, vous re-testez, vous redéployez. Reboot sur ancienne génération : si le service réseau est tombé et que SSH ne répond plus, demandez un reboot via la console de votre fournisseur (Hetzner, OVH, AWS) ; le menu GRUB ou systemd-boot du serveur affichera les générations, choisissez l’avant-dernière.

Étape 7 — Gérer plusieurs serveurs avec colmena ou deploy-rs

Quand vous gérez cinq ou dix serveurs, lancer manuellement nixos-rebuild pour chacun devient pénible. Deux outils orchestrent. colmena lit votre flake, détecte les nixosConfigurations, et déploie en parallèle avec un seul commande. deploy-rs ajoute des health-checks et un rollback automatique si le déploiement échoue.

# Avec colmena (à installer en plus)
colmena apply switch
colmena apply switch --on vps01

# Avec deploy-rs
deploy

Pour démarrer, restez sur nixos-rebuild --target-host simple. Quand le nombre de serveurs justifie l’investissement, colmena est le compromis le plus pragmatique. Le manuel officiel de colmena documente les options avancées.

Étape 8 — Une bande passante limitée : l’astuce du cache local

Sur une connexion mobile ou bridée, télécharger 500 Mo depuis cache.nixos.org à chaque déploiement est rédhibitoire. Solution : ajoutez un cache binaire local sur un serveur du LAN ou un VPS proche, et faites pointer vos serveurs distants dessus.

# Sur le serveur cache (déclaré aussi en NixOS)
services.nix-serve = {
  enable = true;
  secretKeyFile = "/var/cache-priv-key.pem";
};
networking.firewall.allowedTCPPorts = [ 5000 ];

# Sur les serveurs cibles
nix.settings.substituters = [
  "https://cache.nixos.org"
  "http://cache-local.exemple.fr:5000"
];
nix.settings.trusted-public-keys = [
  "cache-local.exemple.fr:..."
];

Désormais, vos serveurs téléchargent d’abord depuis le cache local (LAN, à pleine vitesse) avant de tomber sur cache.nixos.org. Le pattern marche aussi pour des fermes de runners CI qui ont besoin des mêmes paquets.

Erreurs fréquentes

Symptôme Cause Solution
Permission denied (publickey) Clé SSH pas dans authorizedKeys du serveur. Ajouter la clé dans users.users.deploy.openssh.authorizedKeys.keys et faire un premier rebuild local sur le serveur.
error: cannot run sudo on host --use-remote-sudo oublié. Ajouter le flag.
Build extrêmement lent Compilation locale sur poste faible. Utiliser --build-host identique au target.
Le serveur n’a plus de réseau après le rebuild Erreur dans la config réseau. Reboot via console du fournisseur, sélectionner l’avant-dernière génération dans le menu boot.
error: file './hosts/vps01/hardware-configuration.nix' was not found Fichier pas généré ou pas commit. SSH sur le serveur, lancer nixos-generate-config --show-hardware-config, copier la sortie dans le flake local.

Comparer cette approche à Ansible et à Terraform

Ansible est impératif : il décrit des étapes (installer ce paquet, modifier ce fichier, redémarrer ce service) exécutées via SSH. Le résultat dépend de l’état initial du serveur. nixos-rebuild --target-host décrit l’état final souhaité ; le moteur d’évaluation produit un système identique quel que soit le point de départ. Pas de drift possible : si un fichier de config n’est pas dans le flake, il est écrasé au prochain rebuild.

Terraform reste utile pour la couche infra (créer la VM, le réseau, le bucket S3). NixOS prend ensuite le relais pour configurer la VM créée. Les outils terranix permettent même d’écrire le Terraform en Nix, mais c’est une couche d’abstraction supplémentaire à apprendre.

Le combo le plus pragmatique : Terraform pour provisioner les VMs avec une image NixOS minimale, puis nixos-rebuild --target-host pour les configurer.

Workflow Git autour du déploiement

Le pattern qui marche en équipe : un seul dépôt git contient tous les flakes d’infra (infra/), avec un sous-dossier par serveur. Chaque modification fait l’objet d’une PR ; un workflow CI lance nix flake check et nixos-rebuild build --flake .#vps01 pour valider que la config évalue. Le merge sur main déclenche un nixos-rebuild switch --target-host via un runner avec accès SSH aux serveurs.

Cette mécanique transforme le déploiement en simple git push, avec audit complet via git log, revue par pair via PR, et rollback trivial via git revert.

Suite logique

Avec le déploiement distant maîtrisé, deux étapes complémentaires : Gérer les secrets avec agenix pour ne plus jamais commit de credentials en clair, et CI Nix : intégration continue avec flakes pour automatiser les rebuilds sur PR. Le guide principal NixOS reste le hub de la série.

Références officielles

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité