Installation fiable et reproductible de Linux avec NixOS
8 févr. 2022
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
Lors de l’utilisation d’un système d’exploitation, la mise à jour ou l’installation de packages sont des opérations courantes qui présentent un risque pour la stabilité du système. NixOS est une distribution Linux qui assure la fiabilité du système d’exploitation en garantissant la reproductibilité de l’état sytème et de ses états antérieurs.
Cet article prend la suite de notre introduction a Nix en deployant NixOS sur votre machine. Il explique comment fonctionne NixOS, comment l’obtenir et l’installer, et comment Nix garanti la fiabilité du système. Votre machine démarrera avec un système NixOS fonctionnel et vous apprendrez comment NixOS, le gestionnaire de packages Nix, et l’outil Home Manager interagissent ensemble.
Qu’est ce qu’est NixOS ?
NixOS est une distribution Linux. Il est construit sur la base de Nix, un gestionnaire fonctionnel de packages dont le language est inspiré de la programmation fonctionnelle. NixOS exploite la puissance du gestionnaire de packages Nix et l’applique à l’ensemble du système. Cela signifie, entre autres choses, qu’il est facile de restaurer toute la configuration du système à un état antérieur. Complémentaire au système géré par NixOS, Home Manager gère un environnement utilisateur.
Pourquoi NixOS ?
NixOS applique les fondamentaux de Nix à l’ensemble du système. Cela conduit à :
- La reproductibilité du système : étant donné une configuration d’un système (dans un fichier de configuration NixOS), il est possible de reproduire l’intégralité du système (modulo les états changeant, comme le contenu des bases de données par exemple) sur une autre machine.
- Mises à jour et restaurations atomiques : les modifications apportées au niveau du système ou au niveau du package sont toujours réversibles.
- Gestion des dépendances : NixOS utilise la gestionnaire de packages Nix. Nix s’assure que la déclaration des dépendances est complète lors de l’installation d’un package. Étant donné que Nix stocke les packages de manière isolée entre eux, il est possible d’avoir différentes versions du même package installées. Ainsi, différents packages peuvent utiliser différentes versions de la même dépendance sans problème. Cette gestion des dépendances ne conduit pas à des applications avec de larges volumes comme c’est le cas avec flatpack.
Installation de NixOS
La machine utilisée lors de l’installation est un ordinateur portable Dell Precision 5520 avec un SSD de 1 TB et 32 GB de RAM. Les instructions décrites ici s’appliquent à toute machine, qu’il s’agisse d’un ordinateur de développement, d’un ordinateur portable ou d’une machine virtuelle.
Obtention de l’ISO NixOS
L’image ISO de NixOS peut être téléchargée depuis la page de téléchargement de NixOS. Le fichier image ISO est disponible en deux options :
- L’image ISO graphique (choix le plus simple) : avec cette option, l’installation est plus simple car elle dispose d’une interface graphique et de l’accès réseau nécessaire à l’installation du système.
- L’image ISO minimale (non graphique) : c’est l’image ISO minimaliste en matière de contenu. L’avantage est la taille plus petite du fichier image. L’inconvénient est qu’il y a plus à faire avant l’installation. Voici comment préparer l’accès réseau dans le programme d’installation.
L’accès réseau doit être configuré avant l’installation, pour télécharger les dépendances demandées.
Mon installation utilise l’image ISO graphique avec l’environnement de bureau Gnome. La taille est relativement petite, environ 2 GB.
Boot du programme d’installation
L’image .iso
est utilisée pour créer une clé USB bootable. La documentation officielle de NixOS couvre le processus. Suivez la documentation Ubuntu pour une approche plus conviviale utilisant balenaEtcher.
Une fois terminé, redémarrez votre machine cible et démarrez à partir du lecteur USB. L’écran présente une interface graphique à partir de laquelle NixOS peut être configuré et installé. Un premier écran propose plusieurs variantes de l’installateur, sélectionnez la première proposition. Quelques secondes plus tard, Gnome est opérationnel depuis le système de la clé USB. Ouvrez un nouveau terminal.
Partitionnement
Le programme d’installation de NixOS n’effectue ni partitionnement ni formatage. C’est la responsabilité de l’utilisateur. Pour effectuer cette opération, il est nécessaire de connaître le nom du disque dur. La commande ci-dessous permet de connaitre ce nom :
lsblk -p
Dans notre cas, le nom du disque dur est /dev/nvme0n1
. Mais selon la nature du disque (SATA, SSD, NVMe, …), il est également possible d’avoir d’autre noms comme /dev/sda
. Pour la suite de cet article, les commandes sont basées sur le nom de disque /dev/nvme0n1
.
Meni du nom du disque connu, la prochaine étape consiste en son partitionnement. Dans notre cas, une seule partition entièrement dédiée au système d’exploitation. L’hibernation après redémarrage est configuré pour conserver l’état du système sur disque dans l’espace swap. Cette fonctionnalité nécessite la création d’une partition swap. Il n’est pas recommandé d’activer l’hibernation sur un système avec de grandes ressources RAM comme un serveur. Si vous choisissez d’activer l’hibernation, définissez la taille de la partition swap égale à 1,5 fois la taille de la RAM.
Le schéma de partition UEFI est utilisé comme méthode de démarrage. La partition swap utilise 50 GiB. Le schéma de partition MBR est également présenté à des fins d’illustration.
Depuis le terminal, connectez-vous en tant que root
avec sudo su -
. fdisk et Parted sont des outils populaires pour partitionner le lecteur.
-
Exemple de schéma de partition pour NixOS sur /dev/nvme0n1 avec UEFI
# Enter fdisk fdisk /dev/nvme0n1 # Partition 1 g # Create a new empty GTP partition table n # Create a new partition 1 # Partition number of the first partition., default (default) # First sector, default 2048 +512M # Last sector, 512 MB t # Change the partition type 1 # Select the first partition 1 # Use EFI System Partition, or ESP (default) # Partition 2 n # Create a new partition 2 # Partition number of the second partition, default (default) # First sector start at the end of first partition, default 1001472 -50G # Last sector, all disk minus 50G for swap # Partition 3 n # Create a new partition 3 # Third partition (default) # First sector start at the end of second partition (default) # Last sector is the end of the disk t # Change the partition type 3 # Select the third partition 19 # Use Linux swap # Finalize v # Check the settings w # Write and quit
-
Exemple de schéma de partition alternatif pour NixOS sur /dev/nvme0n1 avec MBR
parted /dev/nvme0n1 -- mklabel msdos parted /dev/nvme0n1 -- mkpart primary 1MiB -50GiB parted /dev/nvme0n1 -- mkpart primary linux-swap -50GiB 100%
Formatage
Récapitulatif rapide, dans notre installation, NixOS cible le disque /dev/nvme0n1
. La partition /dev/nvme0n1p2
est la racine du système Linux. La partition /dev/nvme0n1p3
est la partition swap.
Dans cette étape, les objectifs sont de formater les partitions, d’activer la partition swap et de monter le système de fichiers cible sur lequel NixOS va être installé. Voici les commandes pour les démarrages en UEFI et MBR (Legacy boot) :
-
Cas UEFI
# Disk format mkfs.ext4 -L nixos /dev/nvme0n1p2 mkswap -L swap /dev/nvme0n1p3 mkfs.fat -F 32 -n boot /dev/nvme0n1p1 # System mount mount /dev/disk/by-label/nixos /mnt swapon /dev/nvme0n1p3 mkdir -p /mnt/boot mount /dev/disk/by-label/boot /mnt/boot
-
Cas MBR
mkfs.ext4 -L nixos /dev/nvme0n1p1 mkswap -L swap /dev/nvme0n1p2 mount /dev/disk/by-label/nixos /mnt swapon /dev/nvme0n1p2 nixos-generate-config --root /mnt
Configuration de NixOS
L’installation se fait via le fichier de configuration de NixOS présent dans /mnt/etc/nixos/configuration.nix
. Les commandes pour générer le fichier de configuration et l’ouvrir pour modification sont :
nixos-generate-config --root /mnt
nano /mnt/etc/nixos/configuration.nix
Dans la philosophie de NixOS, le fichier de configuration reflète l’ensemble du système. Il comprend les packages à installer, les services à exécuter, les paramètres à appliquer, la configuration réseau et potentiellement bien plus encore. Pour faciliter la compréhension de cet article introductif, nous allons commencer par une configuration minimale, puis la compléter une fois le système redémarré. À l’avenir, nous vous encourageons de versionner et sauvegarder cette configuration. Ainsi, sur une nouvelle installation de machine, vous avez la possibilité de cloner votre configuration et de la réappliquer, entièrement ou un sous-ensemble de celle-ci, à un nouvel environnement cible.
Un fichier de configuration minimal de NixOS ciblant l’environnement de bureau Gnome et la méthode de démarrage UEFI est présenté ci-dessous. Si vous souhaitez démarrer avec un système plus complet, vous pouvez enrichir la configuration avec vos propres propriétés ou utiliser le fichier de configuration, plus exhaustif, proposé à la fin de cet article.
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.wlp2s0.useDHCP = true;
networking.networkmanager.enable = true;
# Enable the X11 windowing system.
services.xserver.enable = true;
# Enable the GNOME Desktop Environment.
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Configure keymap in X11
services.xserver.layout = "fr";
# Enable sound.
sound.enable = true;
hardware.pulseaudio.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
services.xserver.libinput.enable = true;
# Define a user account.
# Don't forget to set a password with ‘passwd’ using the root account if you don't use the initialPassword field.
users.users.florent = {
isNormalUser = true;
initialPassword = "secret"; # Define the user initial password
extraGroups = [ "wheel" ]; # wheel to enable ‘sudo’ for the user.
};
# List packages installed in system profile.
# To search, run: `nix search wget`
environment.systemPackages = with pkgs; [
vim
];
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.05"; # Did you read the comment?
}
Installation
Il s’agit de la dernière étape avant le redémarrage du système. Une connexion internet est nécessaire pour télécharger les dépendances. L’installation reflète le contenu de la configuration créée précédemment. La commande pour lancer l’installation est :
nixos-install
Un mot de passe root est demandé. Une fois terminé, le système est prêt au redémarrage.
Mise à jour de la configuration de NixOS
Le système redémarré, il évoluera selon vos besoins. De nouveaux outils sont installés, des services sont démarrés et la configuration est mise à jour. Cela fait partie du cycle de vie du système, que ce soit pour une machine de développement ou pour un serveur de production.
Les modifications effectuées s’appliquent au système. Ils affectent tous les utilisateurs créés sur la machine, et au niveau de l’utilisateur affectent un utilisateur spécifique. Le fichier de configuration NixOS reflète la configuration au niveau du système. Home Manager est l’outil permettant de gérer de manière déclarative la configuration au niveau de l’utilisateur.
L’ajout du package curl
au niveau système est effectué avec la configuration suivante :
{ config, pkgs, ... }:
{
...
environment.systemPackages = with pkgs; [
vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
curl
];
...
}
Toute modification du fichier de configuration NixOS entraîne une nouvelle configuration de démarrage. Les commandes ci-dessous construisent la configuration déclarée dans le fichier de configuration NixOS et en font la configuration de démarrage par défaut :
nixos-rebuild switch
A chaque application de la commande nixos-rebuild switch
, une nouvelle configuration est disponible au démarrage du système d’exploitation. Voici un exemple d’écran au redémarrage :
La commande pour lister les configurations de démarrage sur NixOS :
sudo nix-env -p /nix/var/nix/profiles/system --list-generations
Notre article introduisant Nix liste les commandes les plus courantes.
Qu’est ce que Home Manager ?
Home Manager est un outil permettant de gérer un environnement utilisateur à l’aide du gestionnaire de packages Nix. Ainsi, il complète NixOS. Il existe deux manières d’utiliser Home Manager :
-
Utilisation de l’outil autonome home-manager
Il permet de gérer le répertoire home d’un utilisateur indépendamment du système dans son ensemble. Il y a deux fichiers de configuration à maintenir dans ce cas : un fichier pour la configuration au niveau du système (
/etc/nixos/configuration.nix
) et un fichier pour la configuration au niveau de l’utilisateur (~/config/nixpkgs/home.nix
). Le premier nécessite des privilèges root tandis que le second est exécuté par l’utilisateur sans les autorisationssudoers
. -
Utilisation en tant que module dans une configuration système NixOS
Il permet de gérer la configuration au niveau du système et la configuration au niveau de l’utilisateur dans un seul fichier (
/etc/nixos/configuration. nix
). Des privilèges de niveau root sont requis pour appliquer les mises à jour de Home Manager.
J’ai trouvé plus facile de conserver la configuration de mon système dans un seul fichier. Après tout, je suis le seul utilisateur de ma machine de développement. Nous couvrons ci-dessous l’installation de Home Manager en tant que module dans la configuration système NixOS.
Home Manager comme module le système NixOS
L’installation de Home Manager en tant que module NixOS nécessite des privilèges de niveau root. Depuis le terminal, connectez-vous en tant que root
avec sudo su -
. Suivez ensuite les étapes ci-dessous pour configurer Home Manager :
-
Utilisez les commandes ci-dessous pour ajouter le channel pour Home Manager :
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager # If you follow a Nixpkgs version 21.11 channel, run nix-channel add https://github.com/nix-community/home-manager/archive/release-21.11.tar.gz home-manager instead of the command below nix-channel --update
-
Ajoutez
dans la sectionimports
du fichier de configuration NixOS. Une nouvelle option NixOS appeléehome-manager.users
est maintenant disponible.
Étant donné l’exemple du fichier de configuration NixOS dans la section Génération et configuration du fichier de configuration NixOS, l’ajout du module Home Manager pour installer le package python3
et configurer le dotfile .git
pour l’utilisateur nommé florent
donne :
{ config, pkgs, ... }:
{
...
# Home Manager configuration for user florent
home-manager.users.florent = { pkgs, ...}: { # List packages to install in user profile home.packages = [
pkgs.python3
];
# Git config for the user
programs.git = {
enable = true;
userName = "Florent";
userEmail = "florent@adaltas.com";
};
};
...
}
Comme précédemment, utilisez nixos-rebuild switch
pour appliquer les modifications.
Conclusion
NixOS applique les principes fondamentaux de Nix à l’ensemble du système pour une expérience Nix holistique. Nix simplifie le processus de sauvegarde, de partage ou de réplication de la configuration des machines. Appliqué à l’échelle du système, il donne naissance à une nouvelle distribution Linux flexible, fiable et reproductible. On imagine aisément l’atrait de ces bénéfices appliqués à des environnements de CI/CD et des clusters distribués.