--- title: Introducción a Nix & NixOS sub_title: Sistemas y paquetes que funcionan donde y cuando quieras author: Pedro Rey --- # Introducción NixOS está de moda === ![](images/nix-star-history-20251215.png) La _temida_ curva de aprendizaje de Nix(OS) === ![](images/nixos-curve.jpg) ¿ Qué es Nix, NixOS, Nixpkgs ? === ## Muchos nombres, muy parecidos no? ![image:width:50%](images/nix-onion.png) Nix === ```bash +exec nix run nixpkgs#cowsay -- Soy un paquete de Nix ``` - Gestor de paquetes - Declarativo - Reproducible - Sencillo Declarativo? === > El usuario especifica el estado final deseado y Nix se encarga de conseguirlo. Nix, el lenguaje === > Sólo existe por y para Nix, el gestor de paquetes: > para describir paquetes y configuraciones, así como sus variantes y composiciones. > **No está pensado para casos de uso generales**. - Sencillo - Funcional - Lazy - Turing completo ```nix +exec let fibonacci = n: if n == 0 then 0 else if n == 1 then 1 else fibonacci(n - 1) + fibonacci(n - 2); in fibonacci 12 ``` Nixpkgs === - Repositorio de paquetes en Nix (y módulos de NixOS) - Incluye tests, funciones de ayuda, etc. - Compilado y probado con Hydra - Subido a `cache.nixos.org` ![](images/repology.png) [De repology.org](https://repology.org) NixOS === ![](images/nixos-logo-25.11-xantusia-lores.png) _Logo de NixOS 25.11 "Xantusia"_ por _Yohann Boniface_ - Nix como gestor de paquetes - _OS as code_ - Se encarga **solo** de la parte declarativa - Datos dinámicos (estado) y **carpeta de usuario**, **NO** ```nix { users.users.john= { isNormalUser = true; home = "/home/john"; description = "John Doe"; extraGroups = [ "wheel" "networkmanager" ]; openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... john@foobar" ]; }; } ``` Home Manager === - Gestión de _dotfiles_ - Independiente de NixOS - Por la comunidad ```nix { programs.zsh = { enable = true; enableCompletion = true; autosuggestion.enable = true; syntaxHighlighting.enable = true; oh-my-zsh = { enable = true; plugins = ["git" "fzf"]; }; shellAliases = { c = "clear"; cd = "z"; }; }; programs.zoxide = { enable = true; enableZshIntegration = true; }; programs.fzf.enable = true; } ``` Ecosistema === - Entornos de desarrollo - Entornos de compilación - Máquinas virtuales en la nube - Imáges de contenedores (more on that later) - NixOps, clan, colmena... ```nix # Construir una imagen de docker para el paquete hello pkgs.dockerTools.buildLayeredImage { name = "nix-hello"; tag = "latest"; contents = [ pkgs.hello ]; } ``` # Nix, el lenguaje ## Modo interactivo ```bash nix repl ``` ``` Welcome to Nix 2.13.3. Type :? for help. nix-repl> 1 + 2 3 ``` ## Espacios ```nix +exec let x = 1; y = 2; in x + y ``` ```nix +exec let x=1;y=2;in x+y ``` ## Attribute sets ### Nix ```nix { string = "hello"; integer = 1; float = 3.141; bool = true; null = null; list = [ 1 "two" false ]; attribute-set = { a = "hello"; b = 2; c = 2.718; d = false; }; # comentarios } ``` ### JSON ```json { "string": "hello", "integer": 1, "float": 3.141, "bool": true, "null": null, "list": [1, "two", false], "object": { "a": "hello", "b": 1, "c": 2.718, "d": false } } ``` ```nix +exec /// let a= /// { /// string = "hello"; /// integer = 1; /// float = 3.141; /// bool = true; /// null = null; /// list = [ 1 "two" false ]; /// attribute-set = { /// a = "hello"; /// b = 2; /// c = 2.718; /// d = false; /// }; /// }; /// in a.attribute-set.c ``` ## `let ... in ...` ```nix +exec let a = 1; in a + a ``` ## `with ...; ...` ```nix +exec let a = { x = 1; y = 2; z = 3; }; in with a; [ x y z ] ``` ## `inherit ...` ```nix +exec let x = 1; y = 2; in { inherit x y; } ``` ## String interpoilation `${...}` ```nix +exec let name = "mundo"; in "hola ${name}" ``` ## Paths ```nix +exec /tmp/no/existe ``` ## Funciones ```nix +exec let f = x: x + 1; in f 1 ``` ```nix +exec let f = x: x.a; v = { a = 1; }; in f v ``` ## Librerías ### `builtins` - Vienen con Nix - Escritas en **C++** ```nix +exec builtins.toString ``` ### `pkgs.lib` - En nixpkgs - Escritas en Nix ```nix +exec let pkgs = import {}; in pkgs.lib.strings.toUpper "lookup paths considered harmful" ``` ### `import` - Parte de `builtins` ```bash +exec echo "1 + 2" > /tmp/file.nix nix-instantiate --eval -E 'import /tmp/file.nix' ``` ## Impuridades ### Path ```bash +exec echo "Hola mundo" > /tmp/data nix-instantiate --eval -E '"${/tmp/data}"' ``` ### Fetchers - `builtins.fetchurl` - `builtins.fetchTarball` - `builtins.fetchGit` - `builtins.fetchClosure` ```nix +exec builtins.fetchurl "https://www.kernel.org/theme/images/logos/tux.png" ``` ## Derivaciones - Nix se usa para escribir derivaciones - Nix ejecuta derivaciones para producir resultados de _compilación_ - Esos resultados se pueden usar como entrada para otras derivaciones ```nix { lib, stdenv, fetchurl }: stdenv.mkDerivation rec { pname = "hello"; version = "2.12"; src = fetchurl { url = "mirror://gnu/${pname}/${pname}-${version}.tar.gz"; sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g"; }; meta = with lib; { license = licenses.gpl3Plus; }; } ``` ```nix +exec let pkgs = import {}; in "${pkgs.hello}" ``` Flakes === - Experimentales - Pero no como piensas - Simplemente un **_wrapper_** para otras configuraciones de Nix - `flake.nix` `flake.lock` ```nix +line_numbers {all|2-6|6-12} { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; }; outputs = { self, nixpkgs, ... }@inputs: { nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem { modules = [ ./configuration.nix ]; }; }; } ``` Configurar NixOS === `/etc/nixos/configuration.nix` ```nix +line_numbers {all|10|12|all} { config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; # ...... nix.settings.experimental-features = [ "nix-command" "flakes" ]; environment.systemPackages = with pkgs; [ git vim wget ]; environment.variables.EDITOR = "vim"; # ...... } ``` Configurar NixOS con Flakes === `/etc/nixos/flake.nix` ```nix +line_numbers {all|11-12|all} { description = "A simple NixOS flake"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; }; outputs = { self, nixpkgs, ... }@inputs: { nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem { modules = [ # Importamos lo que teníamos antes! ./configuration.nix ]; }; }; } ``` Anatomía de un modulo === ```nix {lib, config, options, pkgs, ...}: { # Importar otros modulos imports = [ # ... ./xxx.nix ]; for.bar.enable = true; # Otras declaraciones de opciones # ... } ``` ```nix {all|7|8} { config, pkgs, ... }: { imports = [ (import ./special-fonts-1.nix {inherit config pkgs;}) ./special-fonts-2.nix ]; fontconfig.enable = true; } ``` `lib.mkOverride`, `lib.mkDefault`, and `lib.mkForce` === ```nix {4-7|10|12|all} { # ...... mkOverride = priority: content: { _type = "override"; inherit priority content; }; mkOptionDefault = mkOverride 1500; mkDefault = mkOverride 1000; mkImageMediaOverride = mkOverride 60; mkForce = mkOverride 50; mkVMOverride = mkOverride 10; # ...... } ``` `lib.mkOrder`, `lib.mkBefore`, and `lib.mkAfter` === ```nix { # ...... mkOrder = priority: content: { _type = "order"; inherit priority content; }; mkBefore = mkOrder 500; defaultOrderPriority = 1000; mkAfter = mkOrder 1500; # ...... } ``` Vamos a probar algunas cosas 🙃 === Tips & tricks === - Si usas Git, Nix ignora todos los archivos no trackeados. - `sudo nix-collect-garbage --delete-old` - `sudo nix-store --optimise` ```nix { nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 7d"; }; nix.settings.auto-optimise-store = true; } ``` ¿Preguntas? === ![](images/question-mark.png) Muchas Gracias ❤️ === # Repositorio https://git.peprolinbot.com/peprolinbot/charla-gpul-nixos # Referencias - https://nixos-and-flakes.thiscute.world/ (**recomendado** como guia general a seguir) - https://nix.dev/tutorials/nix-language (documentación oficial) - https://bmcgee.ie/posts/2023/01/nix-and-nixos-a-retrospective/ - https://medium.com/@Erik_Krieg/what-is-nix-nixos-aab5610f0d7f # Otras recomendaciones - [Manual de Nix](https://nix.dev/manual/nix/2.28/) - [Manual de Nixpkgs](https://nixos.org/manual/nixpkgs/stable/) - [Manual de NixOs](https://nixos.org/manual/nixos/stable/) - [nixos.wiki](https://nixos.wiki/) - [Wiki Oficial](https://wiki.nixos.org/) - [awesome-nix](https://github.com/nix-community/awesome-nix) ```bash +image qrencode -t png -m 2 -s 30 -o - "https://git.peprolinbot.com/peprolinbot/charla-gpul-nixos/src/branch/main/enlace_final.md" ```