NixOS : Guide sur cette distribution déclarative
Table des matières
NixOS est une distribution Linux assez innovante qui se distingue par une approche différente de la gestion des paquets et de la configuration du système.
NixOS permet une gestion "déclarative" des configurations, à travers un ou plusieurs fichiers de configuration centraux.
Ça facilite la reproduction des environnements d'une machine à l'autre.
On va pouvoir aussi, entre deux modifications du système revenir rapidement à l'état précédent. On est un peu dans le même concept que les distribs atomique, mais avec en plus une configuration déclarative.
Pour résumer, c'est une distribution gérée avec un Ansible intégré pour ceux qui connaissent Ansible.
On trouverra des resources ici :
- Le manuel : https://nixos.org/manual/nixos/stable
- Le wiki : https://nixos.wiki/wiki/Main_Page
- La page de recherche des paquets et des options : https://search.nixos.org/
Il y a 2 images disponibles en téléchargement sur le site de NixOS (https://nixos.org/download) :
- GNOME
- KDE Plasma
Elles permettent de mettre en place une NixOS très rapidement après une installation graphique, via l'outil d'installation Calamarès.
Cela nous limite à une installation de ces 2 environnements de bureau phares.
Si on veut utiliser NixOS en mode "serveur" ou avec un autre environnement de bureau, on fera l'installation via l'image minimale.
Je vous renvoie vers ce tuto : https://www.linuxtricks.fr/wiki/nixos-installer-nixos-facilement-depuis-l-image-minimale
Le fichier de configuration principal est /etc/nixos/configuration.nix
Il contient ceci sur l'installation que j'ai faite avec l'image GNOME :
Les commentaires sont assez explicites.
Il y a une référence dans le fichier principal au fichier hardware-configuration.nix.
Ce fichier sera différent suivant les machines.
Il prend en compte le partitionnement, les pilotes matériels, le réseau par exemple.
Voici ce qu'il contient sur ma machine virtuelle sous Proxmox :
Les fichiers intégrés sont à placer dans /etc/nixos.
On pourra intégrer d'autres fichiers de configuration dans le fichier configuration.nix. Par exemple, intégrer un fichier adrien.nix, on ajoutera la référence dans la section imports :
Ce fichier devra respecter la syntaxe d'un fichier de configuration NIX :
Après chaque modification de la configuration, il sera nécessaire d'appliquer la configuration.
Cela sera à faire quand on modifie un paramétrage ou qu'on ajoute / supprime des logiciels.
La commande à invoquer sera :
Dans un premier temps, on met à jour la liste des logiciels :
Pour appliquer la mise à jour :
On peut faire du 2 en 1 avec :
Et pour prendre en compte les modifications, on devra redémarrer:
L'upgrade du système se fait en suivant les notes de version de la nouvelle version.
Ici un exemple de mise à niveau de 24.05 à 24.11.
On repère le channel sur lequel on est avec :
Ce qui renvoie :
On bascule sur le nouveau channel via :
On applique la mise à niveau :
ça sera évidemment plus long qu'une mise à jour ou un ajout de logiciel, demandera plus d'espace libre et de ressources !
Et pour prendre en compte les modifications, on devra redémarrer:
Par défaut, les images anciennes sont gardées, ce qui permet de faire un rollback sur une config existante.
Pour lister les images et leur statut :
Voici un retour sur une machine :
Pour supprimer les images de plus de 30j par exemple :
Pour tout supprimer sauf l'image en cours :
On pourra dans le fichier de configuration.nix paramétrer un timer de nettoyage des images via :
L'optimisation (auto-optimise-store) permet de passer sur les images et pour les fichiers identiques les remplacer par des liens symboliques et gégner un peu de plce.
Ensuite, les images plus vieille de 15 jours seront épurées toutes les semaines.
Quand on gèrera les configurations, on aura besoin de https://search.nixos.org/
Sur le site on a 2 sections : Options et Packages.
Les options dans NixOS sont des paramètres de configuration qui définissent le comportement du système ou des services. On y trouvera des configs pour :
- Activer des services
- Paramétrer des services
- Régler des éléments du système (zram, etc.)
- Installer des applications et régrer des paramétrages (vim, éditeur par défaut)
Les packages dans NixOS sont des paquets qu'on va installer sur le système, sous forme de liste. On les listera dans un pavé de configuration avec 1 paquet par ligne comme ceci par exemple :
Voici un exemple de configuration du système :
- J'active le service qemuGuest car je suis dans une VM sous Proxmox
- J'active zram, avec sa configuration par défaut (qui semble être 50% de la RAM)
- Je définit la valeur vm.swapiness à 5 au niveau du système
- Je désactive l'IPv6
Voici un exemple de paquets qui nécessitent quelques options, installés sous la forme programs.XXX :
- htop a plusieurs options possibles de paramétrages, ici, je ne fais qu'installer le logiciel
- J'installe vim, avec tous les modules et je le défini comme éditeur par défaut (va modifier la variable EDITOR)
Voici un exemple pour installer des paquets.
On indiquera sue chaque nouvelle ligne (c'est plus propre) le nom des paquets à installer.
On le fera dans la section environment.systemPackages :
On trouvera le nom des paquets dans : https://search.nixos.org/packages
Ici, un exemple d'excusion de logiciels.
Dans le fichier principal, j'ai GNOME qui est installé (c'est un métagroupe) : services.xserver.desktopManager.gnome.enable
Si on veut exclure dans ce paquet des paquets installés, on le fera ainsi :
Ici, un exemple de configuration de GNOME via dconf.
Dans cet exemple je modifie une valeur dconf :
C'est l'équivalent de :
Introduction
NixOS est une distribution Linux assez innovante qui se distingue par une approche différente de la gestion des paquets et de la configuration du système.
NixOS permet une gestion "déclarative" des configurations, à travers un ou plusieurs fichiers de configuration centraux.
Ça facilite la reproduction des environnements d'une machine à l'autre.
On va pouvoir aussi, entre deux modifications du système revenir rapidement à l'état précédent. On est un peu dans le même concept que les distribs atomique, mais avec en plus une configuration déclarative.
Pour résumer, c'est une distribution gérée avec un Ansible intégré pour ceux qui connaissent Ansible.
On trouverra des resources ici :
- Le manuel : https://nixos.org/manual/nixos/stable
- Le wiki : https://nixos.wiki/wiki/Main_Page
- La page de recherche des paquets et des options : https://search.nixos.org/
Installation graphique
Il y a 2 images disponibles en téléchargement sur le site de NixOS (https://nixos.org/download) :
- GNOME
- KDE Plasma
Elles permettent de mettre en place une NixOS très rapidement après une installation graphique, via l'outil d'installation Calamarès.
Cela nous limite à une installation de ces 2 environnements de bureau phares.
Si on veut utiliser NixOS en mode "serveur" ou avec un autre environnement de bureau, on fera l'installation via l'image minimale.
Installation minimale
Je vous renvoie vers ce tuto : https://www.linuxtricks.fr/wiki/nixos-installer-nixos-facilement-depuis-l-image-minimale
Concepts sur la modification
Fichier configuration.nix
Le fichier de configuration principal est /etc/nixos/configuration.nix
Il contient ceci sur l'installation que j'ai faite avec l'image GNOME :
Code BASH :
# Edit this configuration file to define what should be installed on # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running ‘nixos-help’). { config, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # Bootloader. boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; networking.hostName = "nixos-twitch"; # Define your hostname. # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. # Configure network proxy if necessary # networking.proxy.default = "http://user:password@proxy:port/"; # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; # Enable networking networking.networkmanager.enable = true; # Set your time zone. time.timeZone = "Europe/Paris"; # Select internationalisation properties. i18n.defaultLocale = "fr_FR.UTF-8"; i18n.extraLocaleSettings = { LC_ADDRESS = "fr_FR.UTF-8"; LC_IDENTIFICATION = "fr_FR.UTF-8"; LC_MEASUREMENT = "fr_FR.UTF-8"; LC_MONETARY = "fr_FR.UTF-8"; LC_NAME = "fr_FR.UTF-8"; LC_NUMERIC = "fr_FR.UTF-8"; LC_PAPER = "fr_FR.UTF-8"; LC_TELEPHONE = "fr_FR.UTF-8"; LC_TIME = "fr_FR.UTF-8"; }; # 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.xkb = { layout = "fr"; variant = "azerty"; }; # Configure console keymap console.keyMap = "fr"; # Enable CUPS to print documents. services.printing.enable = true; # Enable sound with pipewire. hardware.pulseaudio.enable = false; security.rtkit.enable = true; services.pipewire = { enable = true; alsa.enable = true; alsa.support32Bit = true; pulse.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’. users.users.adrien = { isNormalUser = true; description = "adrien"; extraGroups = [ "networkmanager" "wheel" ]; packages = with pkgs; [ # thunderbird ]; }; # Install firefox. programs.firefox.enable = true; # Allow unfree packages nixpkgs.config.allowUnfree = true; # List packages installed in system profile. To search, run: # $ nix search wget environment.systemPackages = with pkgs; [ # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. # wget ]; # List services that you want to enable: # Enable the OpenSSH daemon. services.openssh.enable = true; # Open ports in the firewall. # networking.firewall.allowedTCPPorts = [ ... ]; # networking.firewall.allowedUDPPorts = [ ... ]; # Or disable the firewall altogether. networking.firewall.enable = false; # 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 = "24.05"; # Did you read the comment? }
Les commentaires sont assez explicites.
Fichier hardware-configuration.nix
Il y a une référence dans le fichier principal au fichier hardware-configuration.nix.
Ce fichier sera différent suivant les machines.
Il prend en compte le partitionnement, les pilotes matériels, le réseau par exemple.
Voici ce qu'il contient sur ma machine virtuelle sous Proxmox :
Code BASH :
# Do not modify this file! It was generated by ‘nixos-generate-config’ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. { config, lib, pkgs, modulesPath, ... }: { imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; boot.initrd.kernelModules = [ ]; boot.kernelModules = [ "kvm-intel" ]; boot.extraModulePackages = [ ]; fileSystems."/" = { device = "/dev/disk/by-uuid/cc0b1b57-1e2a-49fe-896c-17ea6da1f4d3"; fsType = "ext4"; }; fileSystems."/boot" = { device = "/dev/disk/by-uuid/3B88-DF40"; fsType = "vfat"; options = [ "fmask=0077" "dmask=0077" ]; }; swapDevices = [ ]; # Enables DHCP on each ethernet and wireless interface. In case of scripted networking # (the default) this is the recommended approach. When using systemd-networkd it's # still possible to use this option, but it's recommended to use it in conjunction # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. networking.useDHCP = lib.mkDefault true; # networking.interfaces.ens18.useDHCP = lib.mkDefault true; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; }
Créer ses propres configurations .nix
Les fichiers intégrés sont à placer dans /etc/nixos.
On pourra intégrer d'autres fichiers de configuration dans le fichier configuration.nix. Par exemple, intégrer un fichier adrien.nix, on ajoutera la référence dans la section imports :
Code BASH :
imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ./adrien.nix ];
Ce fichier devra respecter la syntaxe d'un fichier de configuration NIX :
Code BASH :
{ config, pkgs, ... }: { # Contenu du fichier }
Appliquer les modifications
Après chaque modification de la configuration, il sera nécessaire d'appliquer la configuration.
Cela sera à faire quand on modifie un paramétrage ou qu'on ajoute / supprime des logiciels.
La commande à invoquer sera :
Code BASH :
sudo nixos-rebuild switch
Gérer NixOS
Mettre à jour NixOS
Dans un premier temps, on met à jour la liste des logiciels :
Code BASH :
sudo nix-channel --update
Pour appliquer la mise à jour :
Code BASH :
sudo nixos-rebuild switch
On peut faire du 2 en 1 avec :
Code BASH :
sudo nixos-rebuild switch --upgrade
Et pour prendre en compte les modifications, on devra redémarrer:
Code BASH :
sudo systemctl reboot
Upgrade : Changer de branche
L'upgrade du système se fait en suivant les notes de version de la nouvelle version.
Ici un exemple de mise à niveau de 24.05 à 24.11.
On repère le channel sur lequel on est avec :
Code BASH :
nix-channel --list | grep nixos
Ce qui renvoie :
Code TEXT :
nixos https://nixos.org/channels/nixos-24.05
On bascule sur le nouveau channel via :
Code BASH :
nix-channel --add https://channels.nixos.org/nixos-24.11 nixos
On applique la mise à niveau :
Code BASH :
sudo nixos-rebuild switch --upgrade
ça sera évidemment plus long qu'une mise à jour ou un ajout de logiciel, demandera plus d'espace libre et de ressources !
Et pour prendre en compte les modifications, on devra redémarrer:
Code BASH :
sudo systemctl reboot
Faire du ménage dans les images
Par défaut, les images anciennes sont gardées, ce qui permet de faire un rollback sur une config existante.
Pour lister les images et leur statut :
Code BASH :
nixos-rebuild list-generations
Voici un retour sur une machine :
Code :
Generation Build-date NixOS version Kernel Configuration Revision Specialisation
10 current 2024-10-25 13:17:46 24.05.5919.32e940c7c420 6.6.58 *
9 2024-10-23 22:21:40 24.05.5860.89172919243d 6.6.57 *
8 2024-10-23 22:14:37 24.05.5860.89172919243d 6.6.57 *
7 2024-10-23 22:10:39 24.05.5860.89172919243d 6.6.57 *
6 2024-10-23 21:53:02 24.05.5860.89172919243d 6.6.57 *
Pour supprimer les images de plus de 30j par exemple :
Code BASH :
nix-collect-garbage --delete-older-than 30d
Pour tout supprimer sauf l'image en cours :
Code BASH :
nix-collect-garbage -d
On pourra dans le fichier de configuration.nix paramétrer un timer de nettoyage des images via :
Code BASH :
nix.settings.auto-optimise-store = true; nix.gc.automatic = true; nix.gc.dates = "weekly"; nix.gc.options = "--delete-older-than 15d";
L'optimisation (auto-optimise-store) permet de passer sur les images et pour les fichiers identiques les remplacer par des liens symboliques et gégner un peu de plce.
Ensuite, les images plus vieille de 15 jours seront épurées toutes les semaines.
Eleménts de configuration
Ressources à connaitre
Quand on gèrera les configurations, on aura besoin de https://search.nixos.org/
Sur le site on a 2 sections : Options et Packages.
Les options dans NixOS sont des paramètres de configuration qui définissent le comportement du système ou des services. On y trouvera des configs pour :
- Activer des services
- Paramétrer des services
- Régler des éléments du système (zram, etc.)
- Installer des applications et régrer des paramétrages (vim, éditeur par défaut)
Les packages dans NixOS sont des paquets qu'on va installer sur le système, sous forme de liste. On les listera dans un pavé de configuration avec 1 paquet par ligne comme ceci par exemple :
Code TEXT :
environment.systemPackages = with pkgs; [ nmon libreoffice-fresh fastfetch ];
Configuration du système
Voici un exemple de configuration du système :
Code TEXT :
# Pour les VMS : services.qemuGuest.enable = true; # Config systeme zramSwap.enable = true; boot.kernel.sysctl = { "vm.swappiness" = 5; } ; networking.enableIPv6 = false;
- J'active le service qemuGuest car je suis dans une VM sous Proxmox
- J'active zram, avec sa configuration par défaut (qui semble être 50% de la RAM)
- Je définit la valeur vm.swapiness à 5 au niveau du système
- Je désactive l'IPv6
Options pour des programmes
Voici un exemple de paquets qui nécessitent quelques options, installés sous la forme programs.XXX :
Code BASH :
# Programmes programs.htop.enable = true; programs.vim.package = pkgs.vim-full; programs.vim.defaultEditor = true;
- htop a plusieurs options possibles de paramétrages, ici, je ne fais qu'installer le logiciel
- J'installe vim, avec tous les modules et je le défini comme éditeur par défaut (va modifier la variable EDITOR)
Installer des paquets
Voici un exemple pour installer des paquets.
On indiquera sue chaque nouvelle ligne (c'est plus propre) le nom des paquets à installer.
On le fera dans la section environment.systemPackages :
Code BASH :
# Paquets qui n'ont pas d'options environment.systemPackages = with pkgs; [ gnomeExtensions.dash-to-dock gnomeExtensions.appindicator gnome.gnome-tweaks gnome-extension-manager nmon libreoffice-fresh songrec ];
On trouvera le nom des paquets dans : https://search.nixos.org/packages
Exclure des paquets d'un groupe
Ici, un exemple d'excusion de logiciels.
Dans le fichier principal, j'ai GNOME qui est installé (c'est un métagroupe) : services.xserver.desktopManager.gnome.enable
Si on veut exclure dans ce paquet des paquets installés, on le fera ainsi :
Code BASH :
# Exclure les logiciels de GNOME par défaut installés environment.gnome.excludePackages = with pkgs; [ gnome-tour gnome.geary ];
Configuration de GNOME via dconf
Ici, un exemple de configuration de GNOME via dconf.
Dans cet exemple je modifie une valeur dconf :
Code BASH :
# Config GNOME programs.dconf = { enable = true; profiles.user.databases = [ { lockAll = true; # prevents overriding settings = { "org/gnome/desktop/wm/preferences" = { button-layout = ":minimize,maximize,close"; }; }; } ]; };
C'est l'équivalent de :
Code BASH :
gsettings set org.gnome.desktop.wm.preferences button-layout ":minimize,maximize,close"