10 KiB
10 KiB
| title | sub_title | author |
|---|---|---|
| Introducción a Nix & NixOS | Sistemas y paquetes que funcionan donde y cuando quieras | Pedro Rey |
Introducción
NixOS está de moda
La temida curva de aprendizaje de Nix(OS)
¿ Qué es Nix, NixOS, Nixpkgs ?
Muchos nombres, muy parecidos no?
Nix
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
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
NixOS
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
{
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
{
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...
# 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
nix repl
Welcome to Nix 2.13.3. Type :? for help.
nix-repl> 1 + 2
3
Espacios
let
x = 1;
y = 2;
in x + y
let x=1;y=2;in x+y
Attribute sets
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
{
"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
}
}
/// 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 ...
let
a = 1;
in
a + a
with ...; ...
let
a = {
x = 1;
y = 2;
z = 3;
};
in
with a; [ x y z ]
inherit ...
let
x = 1;
y = 2;
in
{
inherit x y;
}
String interpoilation ${...}
let
name = "mundo";
in
"hola ${name}"
Paths
/tmp/no/existe
Funciones
let
f = x: x + 1;
in f 1
let
f = x: x.a;
v = { a = 1; };
in
f v
Librerías
builtins
- Vienen con Nix
- Escritas en C++
builtins.toString
pkgs.lib
- En nixpkgs
- Escritas en Nix
let
pkgs = import <nixpkgs> {};
in
pkgs.lib.strings.toUpper "lookup paths considered harmful"
import
- Parte de
builtins
echo "1 + 2" > /tmp/file.nix
nix-instantiate --eval -E 'import /tmp/file.nix'
Impuridades
Path
echo "Hola mundo" > /tmp/data
nix-instantiate --eval -E '"${/tmp/data}"'
Fetchers
builtins.fetchurlbuiltins.fetchTarballbuiltins.fetchGitbuiltins.fetchClosure
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
{ 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;
};
}
let
pkgs = import <nixpkgs> {};
in "${pkgs.hello}"
Flakes
- Experimentales
- Pero no como piensas
- Simplemente un wrapper para otras configuraciones de Nix
flake.nixflake.lock
{
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
{ 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
{
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
{lib, config, options, pkgs, ...}:
{
# Importar otros modulos
imports = [
# ...
./xxx.nix
];
for.bar.enable = true;
# Otras declaraciones de opciones
# ...
}
{
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
{
# ......
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
{
# ......
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-oldsudo nix-store --optimise
{
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
nix.settings.auto-optimise-store = true;
}
¿Preguntas?
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
qrencode -t png -m 2 -s 30 -o - "https://git.peprolinbot.com/peprolinbot/charla-gpul-nixos/src/branch/main/enlace_final.md"




