Polímata

Enseñando se aprende


Nix + Home Manager

Introducción

Desde hace tiempo, he estado buscando la mejor manera de crear un entorno de desarrollo reproducible que me evite la tediosa tarea de instalar y configurar mis herramientas de trabajo, te estoy hablando a ti VIM. Sé que existen diferentes formas de manejar los famosos archivos .dot, pero quería encontrar una manera de agrupar todo. Fue entonces que me topé con Nix, un lenguaje funcional que actúa como gestor de paquetes y facilita la creación de entornos reproducibles; inclusive existe una distribución de Linux que gira en torno a Nix, se llama NixOs y como podrás adivinar, permite configurar tu sistema y paquetes de manera declarativa y reproducible. Volviendo al tema, estuve varios días partiendome la cabeza intentando entender la sintáxis del lenguaje, pero al final logré mi cometido. Aquí te contaré cómo.

Instalación

Nix

La instalación de Nix es sencilla. Basta con abrir tu distribución e ingresar:

1# Instalación multiusuario
2sh <(curl -L https://nixos.org/nix/install) --daemon
3
4# Instalación usuario
5sh <(curl -L https://nixos.org/nix/install) --no-daemon
6
7# Para probar tu instalación, ingresa
8nix --version
9# Si no tienes respuesta, te recomiendo reiniciar tu distro

Home-Manager

Vale, asumiendo que tienes una instalación de Nix funcional, procederemos a instalar Home-manager, una herramienta que nos permitirá gestionar nuestro entorno de usuario de tal forma que podremos declarar los paquetes que queramos y sus respectivas configuraciones.

 1# Añadimos el canal, aka. apt-add <reppo> 
 2nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
 3
 4# Actualizamos sistema, aka. apt update
 5nix-channel --update
 6
 7# Instalamos, aka. apt install
 8nix-shell '<home-manager>' -A install
 9
10# Verificamos la instalación
11home-manager --version

Listo, lo único que resta es editar el archivo de configuración de home-manager ubicado en $HOME/.config/nixpkgs/home.nix.

Configurando nuestro entorno

Editar home.nix puede ser tan difícil como tu desees. Todo depende del nivel de personalización que le quieras dar. El siguiente código puede servirte para empezar:

 1{ config, pkgs, ... }:
 2
 3{
 4    # Home manager necesita información sobre ti y
 5	# el directorio que manejará
 6	home.username = "<usuario>";
 7	home.homeDirectory = "/home/<usuario>";
 8
 9    /* Este valor determina la versión de Home Manager con la que
10	tu configuración es compatible. Esto ayuda a evitar errores
11	cuando una nueva versión es incompatible con versiones previas.
12
13	Puedes actualizar Home Manager sin cambiar este valor. Vea las
14	notas de versión de Home Manager para una lista de los cambios
15	de cada lanzamiento.
16	*/
17    home.stateVersion = "23.11";
18
19
20	# Paquetes a instalar rápidamente
21	home.packages = with pkgs; [
22	  /*
23        vim 
24		.
25		.
26		.
27		*/
28    ];
29
30    # Manejo de dotfiles
31    home.file = {
32        # Bash
33        ".bashrc".source = <ruta>/.bashrc;
34        ".bash_aliases".source = <ruta>/.bash_aliases;
35    };
36
37
38	# Paquetes a instalar y configurar
39	programs = {
40	    /*
41		e.g
42		git = {
43          enable = true;
44          userName = "<usuario>";
45          userEmail = "<email>";
46        };
47		.
48		.
49		.
50		*/
51    };
52
53	# Opcional ** Variables de la sesión
54	home.sessionVariables = {
55	  EDITOR = "<editorDeTexto (e.g. vim)>";
56    };
57
58	# Permite que Home Manager se instale y configure a si mismo
59	programs.home-manager.enable = true;
60}

Puedes utilizar el buscador y la wiki de NixOs para encontrar más paquetes y sus respectivas opciones de configuración. Al final, podrías terminar con un archivo como el mío. Una vez que hayas terminado, hay que activar la configuración con el siguiente comando:

home-manager switch

Y eso es todo, ya tienes un entorno funcional de desarrollo. Te recomiendo crear un repositorio para descargarlo y activarlo cada vez que lo necesites.

Manejo de versiones

Para concluir, me gustaría hablar sobre el concepto de generación. Cada vez que realizamos un cambio en nuestra configuración, tanto en Nix como en Home Manager, se produce una nueva generación. En caso de que tengamos algún problema con los nuevos cambios, siempre podemos volver a la versión anterior. Para listar y manipular las generaciones que tenemos respaldadas se utilizan los siguientes comandos:

Nix

 1# Lista las generaciones
 2nix-env --list-generations
 3
 4# Regresar a la generación anterior
 5nix-env --rollback
 6
 7# Cambia a una generación en específico
 8nix-env --switch-generation <id-generación>
 9
10# Borrar ciertas generaciones
11nix-env --delete-generations <id-generaciones separados por espacios>
12
13# Borrar las generaciones excepto las últimas <N>
14nix-env --delete-generations +<N>
15
16# Borrar todas las generaciones excepto la actual
17nix-env --delete-generations old
18
19# Recolección de basura
20nix-collect-garbage

Home Manager

1# Lista las generaciones
2home-manager generations
3
4# Borrar ciertas generaciones
5home-manager remove-generations <id-generaciones separados por espacios>
6
7# Borrar generaciones anteriores a <timestamp> (e.g. -30 days)
8home-manager expire-generations <timestamp>

Aún no es posible realizar cambiar de generación en home-manager con un simple comando, pero la manera de hacerlo es la siguiente:

  1. Lista las generaciones e identifica la ID de tu preferencia: home-manager generations
  2. Copia la ruta a la que apunta esa ID -> (e.g./nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation)
  3. Ejecuta el script activate de la ruta: /nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation/activate.

Bibliografía