DevBox
Devbox es una herramienta de línea de comandos que permite crear shells aislados para desarrollo sin la necesidad de contenedores Docker o máquinas virtuales. Devbox utiliza el gestor de paquetes Nix para instalar los paquetes necesarios.
Definimos las dependencias del proyecto en un archivo devbox.json, garantizando que todos en el equipo utilicen las mismas versiones de herramientas y bibliotecas. Esto elimina problemas comunes de configuración y facilita la integración continua.
- Evita configurar manualmente herramientas y bibliotecas en el pipeline de CI.
- Rapidez en la configuración
- Portabilidad para entornos
- En el caso de contenedores podemos mantener una base específica en lugar de preparar diferentes runners.
Además, Devbox permite exportar tu entorno de desarrollo a contenedores o entornos en la nube, garantizando portabilidad y consistencia entre desarrollo local y producción.
En resumen, Devbox es una solución eficiente para crear entornos de desarrollo aislados, consistentes y portables, simplificando el flujo de trabajo y mejorando la productividad del equipo.
Se define la lista de paquetes necesarios para tu proyecto, y Devbox crea un entorno aislado y reproducible con esos paquetes instalados.
DevBox vs NIX
Tuve una experiencia con la distribución NixOS y conocí el gestor de paquetes Nix. En aquel momento quería utilizarlo en mi escritorio personal pues quería un entorno que pudiera replicar rápidamente y encontrar una alternativa para mi proyecto Workstation con Ansible. La idea es maravillosa, pues NixOS permite que configuremos el sistema operativo de forma declarativa y adopta el concepto de inmutabilidad. Cada cambio genera un nuevo estado permitiendo rollout. Acabé abandonando la idea de usarlo en mi escritorio personal pues vi que era muy trabajoso, pero me encantó la idea y ya pensé en su uso para varios escenarios, no para mi escritorio personal. Existe una herramienta llamada nix-shell que es un shell temporal. Todo lo que instalas mientras está activo se descarta cuando cerramos la sesión y esto parecía muy prometedor.
La barrera de entrada para el uso de Nix es grande. Es necesario estudio, persistencia y mucha paciencia. No es una tecnología que podamos aplicar fácilmente en una empresa, pues exigirá esfuerzo de muchas personas para aprender. ¡Es ahí donde entra DevBox resolviendo este problema!
Devbox utiliza Nix como base, incluyendo funcionalidades similares a nix-shell, pero ofrece una experiencia simplificada y orientada al desarrollo. Devbox abstrae muchas de las complejidades de nix-shell y del ecosistema Nix, haciendo más fácil para los desarrolladores crear y gestionar entornos de desarrollo reproducibles. Disminuyendo la complejidad se volvió mucho más fácil proponer su uso dentro del equipo, pues vamos a usar Nix sin saber sobre Nix de una manera mucho más amigable.
Con DevBox podemos crear el entorno sin contaminar el escritorio o necesitar cambiar configuraciones del sistema para ejecutar el proyecto creando una sesión shell exclusiva para el proyecto. Generalmente hacemos esto con uso de contenedores, pero con DevBox eliminaremos toda la complejidad y problemas que involucran el uso de contenedores.
Instalación
Si estás en Windows es necesario el uso de WSL pues se necesita un entorno Linux. En Mac funciona perfectamente.
curl -fsSL https://get.jetify.com/devbox | bash
devbox version
0.13.7
Utilizando DevBox
Crea una carpeta de prueba cualquiera simulando un proyecto.
mkdir prueba
cd prueba
Ahora vamos a iniciar un devbox.json, es decir, un archivo que será la descripción de todo lo que este entorno necesita.
devbox init
ls
devbox.json
cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
Para entrar e iniciar un shell devbox a partir de lo que tenemos ahí.
❯ devbox shell
Starting a devbox shell...
A partir de ahora estamos usando el shell devbox. Para confirmar si quieres solo haz un env en el terminal y ve las diferencias de las variables de entorno
❯ env | grep NIX
Para salir de este shell solo escribe exit y rehaz el env anterior y verás que no tendremos todas esas variables anteriores.
exit
# Volviendo al shell anterior podemos ver que la salida es mucho menor teniendo solamente las variables por defecto de devbox.
env | grep NIX
Por ejemplo no tengo el binario yq en mi máquina, pero tampoco quiero instalarlo, solo para este proyecto
yq
zsh: command not found: yq
Entonces vamos a empezar a añadir las cosas que necesitamos. Recuerda estar dentro del shell con el comando devbox shell.
# Añadiendo yq
devbox add yq
Info: Adding package "yq@latest" to devbox.json
Info: Installing the following packages to the nix store: yq@latest
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.
yq --version
yq 3.4.3
# Observa que entró en devbox.json en packages
cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": ["yq@latest"],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
Si salimos del terminal y volvemos, yq estará ahí.
Para eliminar solo necesitamos usar rm en lugar de add.
devbox list
* yq@latest - 3.4.3
devbox rm yq
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.
❯ cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
Ahora vamos a ponerlo nuevamente manualmente. No lo tenemos instalado. Sal del devbox con el comando exit y edita devbox.json incluyendo el paquete como teníamos arriba e inicia nuevamente.
# Para salir del shell devbox
exit
# Edita el archivo incluyendo el paquete
❯ cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [
"yq@latest"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
# Iniciando y ya instala para nosotros
❯ devbox shell
Info: Ensuring packages are installed.
✓ Computed the Devbox environment.
Starting a devbox shell...
yq --version
yq 3.4.3
Para buscar un paquete solo usa devbox search nombre_del_paquete. Nunca instales latest, procura fijar versiones de todo pues devbox nos da el poder para eso.
En mi máquina fuera del shell tengo terraform instalado.
terraform version
Terraform v1.10.3
Vamos a instalar otra versión dentro del proyecto (terraform 1.9.8). Podríamos simplemente hacer devbox add [email protected] pero vamos a hacerlo de manera diferente para aprender algunos detalles.
# Listando los paquetes usando search.
devbox search terraform
Found 25+ results for "terraform":
* terraform (1.10.3, 1.10.2, 1.10.1, 1.10.0, 1.9.8, 1.9.7, 1.9.6, 1.9.5, 1.9.4, 1.9.3 ...)
* terraform-compliance (1.3.49, 1.3.48, 1.3.47, 1.3.46, 1.3.45, 1.3.44, 1.3.43, 1.3.34, 1.2.11)
* terraform-docs (0.19.0, 0.18.0, 0.17.0, 0.16.0, 0.15.0, 0.14.1, 0.13.0, 0.12.1, 0.12.0, 0.11.2 ...)
* terraform-full (1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.9, 1.1.8, 1.1.7 ...)
* terraform-inventory (0.10, 0.7-pre)
* terraform-landscape (0.2.1)
* terraform-local (0.20.0, 0.19.0, 0.18.2)
* terraform-ls (0.36.3, 0.36.2, 0.36.0, 0.34.3, 0.34.2, 0.34.1, 0.33.1, 0.33.0, 0.32.8, 0.32.7 ...)
* terraform-lsp (0.0.12, 0.0.10)
* terraform_1 (1.3.9, 1.3.5, 1.3.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.9, 1.1.8, 1.1.7 ...)
Warning: Showing top 10 results and truncated versions. Use --show-all to show all.
# Edita directamente el archivo devbox.json incluyendo el paquete.
❯ cat devbox.json
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [
"yq@latest",
"[email protected]"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
# Ejecutando devbox install instalará todos los paquetes que encuentre en devbox.json
devbox install
Info: Ensuring packages are installed.
Info: Installing the following packages to the nix store: [email protected]
✓ Computed the Devbox environment.
Warning: Your devbox environment may be out of date. Run refresh to update it.
Finished installing packages.
# ¿Extraño verdad? Debería ser 1.9.8
# Esto sucedió porque aún está referenciando terraform de mi máquina que es accesible para él.
# Es necesario hacer un refresh
terraform --version
Terraform v1.10.3
# Saliendo y volviendo
exit
devbox shell
Starting a devbox shell...
terraform --version
Terraform v1.9.8
# Saliendo a mi sistema
exit
terraform version
Terraform v1.10.3
Instalando directamente sin hacer este malabarismo no sucede esto.
Podemos observar que tenemos la carpeta oculta .devbox en el proyecto. Es en esta carpeta donde tenemos los paquetes de forma aislada del sistema. Para un proyecto real recuerda poner esto en .gitignore para no subir esto a los repositorios.
ls -lha
total 8,0K
drwxr-xr-x 5 davidprata 160 Jan 13 08:09 .
drwxr-x---+ 53 davidprata 1,7K Jan 13 09:08 ..
drwx------ 10 davidprata 320 Jan 13 09:15 .devbox
-rw-r--r-- 1 davidprata 355 Jan 13 09:00 devbox.json
-rw-r--r-- 1 davidprata 3,8K Jan 13 08:53 devbox.lock
Eliminar la carpeta del proyecto eliminará todo lo que fue instalado para su ejecución.
Ahora imagina el poder de esto dentro de un pipeline y cuánto podríamos facilitar el desarrollo y disminuir código. Sería prácticamente poner el runner para ejecutar el shell devbox que ya instala todo lo necesario. Disminuiríamos varios steps de los pipelines y podríamos reaprovechar la misma definición en varios proyectos.
Además tener todas las dependencias declaradas dentro de un archivo en el repositorio facilitará el concepto de GitOps.