Portafolio profesional

Mi entorno de desarrollo en Arch Linux: automatizando dotfiles con perfiles portátiles

Como arquitecto backend, mi productividad depende de un entorno de desarrollo confiable. En este artículo te muestro cómo automatizé la configuración completa de mi Arch Linux, desde Hyprland hasta Neovim, y el truco de los perfiles portátiles que me salva cuando cambio de máquina.

Artículo

# Mi entorno de desarrollo en Arch Linux: automatizando dotfiles con perfiles portátiles ## El problema Como desarrollador que trabaja en varios proyectos y a veces necesita cambiar de equipo o reinstalar el sistema, perdía horas valiosas configurando mi entorno cada vez. Tenía que recordar decenas de paquetes de Arch Linux, recrear configuraciones complejas para Hyprland, Neovim con LazyVim, Waybar, y asegurarme de que todos los servicios como NetworkManager estuvieran funcionando. El proceso manual era propenso a errores: olvidaba algún paquete, un symlink se rompía, o la configuración de Neovim no cargaba los plugins correctamente. Necesitaba una solución que me permitiera replicar mi entorno exacto, con todas mis preferencias y herramientas, en minutos, no en horas. ## Por qué un script Bash con selectores de modo Podría haber usado herramientas como Ansible, Chef, o incluso contenedores. Pero para dotfiles, quería algo simple, transparente y que no añadiera otra capa de abstracción. Un script Bash me da control total sobre cada paso: instalar paquetes con `yay`, crear symlinks, y configurar servicios. La clave fue añadir el selector de modo `normal` vs `portable`. El modo `normal` es para mi máquina diaria: instala Hyprland, Neovim, y todas mis apps de desarrollo. El modo `portable` va más allá: incluye múltiples kernels (`linux`, `linux-lts`, `linux-zen`), configura GRUB con un tema personalizado, y prepara todo para un USB booteable o una instalación temporal. Este enfoque me permite tener un único repositorio que cubre ambos casos de uso sin duplicar código. ## Arquitectura El flujo principal del sistema está gobernado por el script `install.sh`, que orquesta todo el proceso de configuración. A continuación podés ver cómo interactúan los componentes clave: ```mermaid flowchart LR Usuario["Usuario Ejecuta install.sh"] -- elige --> Selector["install.sh Selector de modo"] Selector -- modo normal/portable --> Instalador["install.sh Instalador de paquetes"] Instalador -- comando yay --> Sistema["Sistema Arch Linux Gestor de paquetes"] Selector -- rutas de configuración --> Linker["apply.sh Creador de symlinks"] Linker -- enlaces simbólicos --> FS["Sistema de archivos ~/.config, ~/.zshrc, etc."] Instalador -- habilita --> Servicios["Systemd NetworkManager, Bluetooth"] NOTE["Evidence gap: No se muestra la lógica interna de apply.sh ni la estructura de carpetas fuente"] Linker --> NOTE ``` Como muestra el diagrama, el usuario ejecuta el script principal `install.sh`, que primero presenta un selector para elegir entre el modo `normal` y `portable`. Esta decisión dirige el proceso de instalación de paquetes (`yay`) y luego activa el script `apply.sh`, que es el responsable de crear todos los enlaces simbólicos desde el repositorio clonado hacia las ubicaciones correctas en el sistema del usuario (como `~/.config/nvim` o `~/.zshrc`). Finalmente, se habilitan servicios esenciales como NetworkManager. Un punto a notar es que la evidencia del repositorio no detalla la lógica interna de `apply.sh` ni la estructura exacta de las carpetas fuente, lo que representa un área donde la documentación podría mejorarse. **Decisiones arquitectónicas clave:** 1. **Repositorio monolítico con estructura modular:** En lugar de múltiples repositorios para cada herramienta, organicé todo en un solo repo con carpetas como `wm/`, `editors/`, `shell/`. Esto simplifica el clonado y el backup, y `apply.sh` puede recorrer estas carpetas para crear symlinks de manera consistente. 2. **Separación entre instalación y aplicación:** `install.sh` maneja la instalación de paquetes (que es lenta y requiere sudo), mientras que `apply.sh` solo crea los symlinks (rápido y sin privilegios). Esto me permite reaplicar configuraciones rápidamente después de un cambio en los dotfiles, sin tener que reinstalar todo. 3. **Configuración de Neovim basada en LazyVim:** En lugar de mantener mi propia configuración de Neovim desde cero, partí de la distribución LazyVim. Esto me da una base sólida y actualizada con lazy loading de plugins. Mi personalización va en `editors/nvim/lua/config/` y `editors/nvim/lua/plugins/`, extendiendo sin sobreescribir. 4. **Perfil portable como superconjunto:** El modo `portable` no es un sistema separado, sino el modo `normal` más un conjunto adicional de paquetes (kernels múltiples, herramientas de boot) y configuraciones (GRUB). Esto maximiza la reutilización y asegura que mi entorno de desarrollo principal esté siempre presente. ## El trade-off que nadie te cuenta El mayor trade-off fue la **fragilidad de los symlinks y la gestión de rutas absolutas**. Al principio, `apply.sh` asumía que el repositorio siempre estaba clonado en `~/mis-dotfiles`. Cuando intentaba usarlo desde una ruta diferente o en el modo portable (que enlaza a `~/.local/share/mis-dotfiles-portable`), los symlinks se creaban apuntando a ubicaciones incorrectas, rompiendo las configuraciones. La solución fue hacer que el script **calcule dinámicamente la ruta fuente** al inicio. Usé `DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"` para obtener la ubicación absoluta del script, independientemente de dónde se ejecute. Luego, todos los comandos `ln -sf` usan `$DIR` como prefijo para las rutas fuente. Este cambio hizo que el sistema fuera verdaderamente portable y robusto. ## Resultado * **Tiempo de configuración reducido de horas a ~15 minutos:** Una nueva instalación de Arch Linux con mi entorno completo, incluyendo el modo portable, ahora toma el tiempo de ejecución del script, no mi atención. * **Consistencia garantizada entre máquinas:** Ya sea en mi laptop principal, una máquina virtual, o un USB booteable, obtengo exactamente el mismo entorno de Hyprland, los mismos atajos de teclado en Neovim, y la misma barra de Waybar. * **Mantenimiento centralizado:** Cuando actualizo un plugin de Neovim o cambio un tema de Hyprland, simplemente hago commit y push a este repositorio. Para aplicar los cambios en todas mis máquinas, solo ejecuto `./apply.sh`. * **Perfil portable funcional:** Tengo una imagen de sistema completa y personalizada en un USB, lista para bootear en cualquier hardware compatible, con múltiples kernels para mayor compatibilidad y todas mis herramientas de desarrollo preinstaladas. ## Lo que haría diferente Invertiría más tiempo al principio en hacer el sistema **idempotente**. El script actual asume un estado inicial limpio (Arch Linux fresco). Si se ejecuta dos veces, puede intentar reinstalar paquetes ya existentes o sobreescribir symlinks (aunque `ln -sf` maneja esto). Si empezara de nuevo, agregaría checks para verificar si un paquete ya está instalado (`yay -Q`), o si un symlink ya existe y apunta al lugar correcto, haciendo el script seguro para ejecutar múltiples veces. Esto lo haría más robusto para actualizaciones incrementales. ¿Querés profundizar en algún componente? Contactame o revisá el código en https://github.com/Albarracin-sg/MIS-DOTFILES.