Este repositorio aprovisiona una estación de trabajo Pop!_OS o Ubuntu con una estrategia en dos capas:
- Ansible gestiona tanto la capa base del sistema operativo (repositorios APT, paquetes del sistema, Docker, Flatpak guiado por facts, integración con el gestor de archivos) como el entorno de usuario (Zsh, Oh My Zsh, herramientas de desarrollo, variables de entorno y el timer de limpieza periódica).
- Nix se mantiene instalado únicamente para
nix shell/nix developy la integración condirenv; ya no gestiona paquetes de usuario ni dotfiles (ver «Migración desde Home Manager» más abajo). - El DevContainer permite validar, lintar y evolucionar la configuración sin contaminar el host.
dotfiles/
├── .devcontainer/
│ ├── devcontainer.json
│ └── Dockerfile
├── .ansible-lint
├── ansible.cfg
├── ansible/
│ ├── group_vars/
│ │ └── all/
│ │ └── main.yml
│ ├── inventories/
│ │ └── local/
│ │ └── hosts.yml
│ ├── local.yml
│ └── roles/
│ ├── common/
│ ├── system/
│ ├── apt_repositories/
│ ├── desktop_apps/
│ ├── virt_manager/
│ ├── flatpak/
│ ├── docker/
│ ├── file_manager/
│ ├── nix/
│ ├── dev_tools/
│ └── shell_config/
├── nix/
│ └── flake.nix
├── bootstrap.sh
└── README.md
- En el host Pop!_OS o Ubuntu real, ejecuta
./bootstrap.sh. - El script instala
git,curlyansiblesolo si faltan, clona el repositorio en~/my-workstationdesdehttps://github.com/techlogycs/my-workstation.gitpor defecto si hace falta y lanza el playbook local. - El playbook configura APT y, según los flags de
ansible/group_vars/all/main.yml, instala VS Code, Brave, Docker, virt-manager con libvirt, RustDesk nativo, Warp Terminal, Flatpak en Ubuntu y Pop!_OS, integración con el gestor de archivos y el binario de Nix (solo paranix shell/nix develop). - El rol
dev_toolsinstala bun, uv, dust y Node.js (vía NodeSource); el rolrustupprovee el toolchain de Rust necesario para compilar dust. - Finalmente, el rol
shell_configinstala Oh My Zsh, plantea~/.zshrc(aliases, integración con Nix/direnv, autosuggestions/syntax-highlighting) y activa el timerworkstation-auto-clean.npm/npxvienen del paquetenodejsde NodeSource, sin alias ni wrapper hacia Bun.
El playbook usa roles pequeños y etiquetados para que puedas ejecutar solo una parte del aprovisionamiento:
common: validación del host y facts compartidos.system: paquetes base, herramientas de escritorio y shell por defecto.apt_repositories: repositorios y llaves APT de proveedores.desktop_apps: instalación de VS Code, Brave y RustDesk nativo.virt_manager: stack de virtualización local con libvirt y virt-manager.flatpak: Flathub y aplicaciones Flatpak por distro.docker: configuración dedaemon.jsony servicio.file_manager: integración “Open in Code”.nix: instalación del binario de Nix (solo paranix shell/nix develop, sin Home Manager).dev_tools: instala bun, uv, dust (vía cargo) y Node.js (vía NodeSource).shell_config: Oh My Zsh, plantilla de~/.zshrcy timerworkstation-auto-clean.apt-clean: elimina definiciones legacy de repositorios APT gestionados por el repo, purga paquetes huérfanos y limpia la caché local de APT.nix-clean: garbage collection genérico del store de Nix (make nix-clean).nix-migrate-single-user: desinstala una instalación multiusuario existente de Nix y reprovisiona Nix en modosingle-user.nix-teardown: desinstala una activación previa de Home Manager en hosts que migraron desde la versión anterior de este repo (ver «Migración desde Home Manager»).migrate: encadenanix-teardowncon la limpieza de artefactos huérfanos de migraciones internas de este repo (el antiguoCARGO_HOMEpersonalizado en~/.local/share/cargo, los wrappers de Bun paranpm/npx/yarn/pnpm); idempotente, seguro de correr aunque no aplique nada.
Ejemplos:
ansible-playbook ansible/local.yml --tags docker
ansible-playbook ansible/local.yml --tags virt-manager
ansible-playbook ansible/local.yml --tags nix,file-manager
ansible-playbook ansible/apt-clean.yml
ansible-playbook ansible/nix-clean.yml
ansible-playbook ansible/nix-migrate-single-user.yml
ansible-playbook ansible/nix-teardown.yml
ansible-playbook ansible/migrate.yml
make install-feature features=thunderbird
make apt-clean
make nix-clean
make nix-migrate-single-user
make nix-teardown
make migrate
./bootstrap.sh --only-feature thunderbird
./bootstrap.sh --tags systemEl contenedor existe únicamente para desarrollo y validación de la configuración. Incluye:
ansible-lintyyamllintpara Ansible/YAML.nix,statixynixpkgs-fmtpara evaluar, lintar y formatear la configuración Nix (elflake.nixrestante solo expone undevShelly checks de lint, ya sin Home Manager).- Extensiones de VS Code orientadas a Ansible, Nix y TOML.
La imagen del DevContainer instala directamente ansible-core, ansible-lint, yamllint y Nix. Después, postCreateCommand solo añade statix y nixpkgs-fmt al perfil del usuario y ejecuta nix flake check --impure sobre nix/.
Si ya tenías el DevContainer creado antes de estos cambios, reconstruye el contenedor para que las herramientas nuevas queden disponibles en PATH.
Dentro del DevContainer o en una máquina con las dependencias instaladas:
make lint
make format
ansible-playbook --syntax-check ansible/local.yml
ansible-lint ansible
yamllint .
DOTFILES_USER="$USER" DOTFILES_HOME="$HOME" NIX_SYSTEM="$(nix eval --impure --raw --expr builtins.currentSystem)" nix --extra-experimental-features "nix-command flakes" flake check --impure ./nixEl Makefile expone también objetivos separados:
make lint-ansiblemake lint-nixmake format-ansiblemake format-nixmake install-feature features=thunderbirdmake apt-cleanmake nix-migrate-single-usermake nix-clean
Los componentes opcionales están controlados desde ansible/group_vars/all/main.yml:
- Todos los
feature_flags.*aceptanenabled,disabledoauto. Los booleanos antiguos siguen funcionando porque se normalizan internamente a esos modos. feature_flags.vscode,feature_flags.brave,feature_flags.docker,feature_flags.nixyfeature_flags.git_credential_oauthusanenabledpor defecto. Hoy en díaautose resuelve igual queenabledpara esos componentes, porque no hay una detección de alternativa equivalente.- Si detecta
docker-desktop, el playbook falla de forma explícita antes de instalar Docker Engine. Para reemplazarlo, debes aprobarlo condocker_desktop_cleanup_approved: true; ese flujo elimina el paquetedocker-desktop, migra~/.docker/config.jsonquitandocredsStoreycurrentContext, crea un backup~/.docker/config.json.docker-desktop.bakcuando hace cambios y borra~/.docker/desktop. feature_flags.virt_managerusadisabledpor defecto; cuando lo activas instala libvirt, QEMU y virt-manager, arrancalibvirtd, añade el usuario objetivo a los gruposlibvirtykvm, y fijaqemu:///systemcomo URI por defecto de libvirt para la sesión de usuario.feature_flags.openvpnusaautopor defecto; cuando detectanetwork-manageren el host instala el backend mínimo de OpenVPN que NetworkManager necesita para las conexiones VPN nativas. Si el host no usa NetworkManager,autono arrastra ese stack por sorpresa; en ese caso soloenabledfuerza la instalación.feature_flags.thunderbirdusadisabledpor defecto; cuando lo activas, instalaorg.mozilla.Thunderbirdvía Flatpak.feature_flags.desktop_toolsusaautopor defecto y solo instala tooling específico de escritorio cuando detecta una base compatible.feature_flags.clipboard_historyusaautopor defecto y convierte Ringboard (clipboard-history con GUI Iced) en el gestor de portapapeles preferido cuando no detecta otro ya instalado.feature_flags.copyqqueda como vía legacy y usadisabledpor defecto; solo conviene activarlo explícitamente si quieres seguir en CopyQ.feature_flags.office_suiteusaautopor defecto y solo instala LibreOffice si no detecta otra suite ofimática ya instalada.feature_flags.file_manager_integrationusaautopor defecto y solo habilita la integración si VS Code también está habilitado.feature_flags.git_credential_oauthmigra la autenticación HTTP(S) de Git a Git Credential Manager, instalado desde un.debupstream fijado por versión y checksum para Ubuntu y Pop!_OS.- La configuración global de Git pasa a usar
credential.helper=/usr/local/bin/git-credential-managerycredential.credentialStore=secretservice, de modo que los tokens quedan persistidos en el keyring del escritorio y sobreviven reinicios. - Si el host tiene una sesión GNOME, Pop o COSMIC y habilitas VS Code o Git Credential Manager, el playbook instala
gnome-keyringpara que exista un proveedor Secret Service/libsecret y no aparezca el warning de keyring en VS Code. - El playbook elimina
git-credential-oauthy mantiene el repositorio estable de git-core en Ubuntu y Pop!_OS para instalar una versión upstream reciente de Git, compatible con Git Credential Manager. - Los repositorios APT gestionados directamente por este repo para Microsoft, Docker y git-core usan keyrings dedicados bajo
/etc/apt/keyrings, y el flujoapt-cleanborra definiciones legacy conocidas para evitar entradas duplicadas o avisos portrusted.gpgenapt. apt_base_packagesincluyeripgrep(antes también se instalaba por duplicado vía Home Manager; ahorargviene solo de APT).distro_flatpak_appsdefine las aplicaciones de escritorio vía Flatpak por distro, excluyendo RustDesk porque se instala de forma nativa.rustdesk_versionaceptalatest(por defecto) o una versión fija; el paquete.debse resuelve desde los metadatos de GitHub y se verifica su SHA-256 antes de instalar.rustdesk_release_arch_maptraduce la arquitectura Debian detectada al sufijo usado por los artefactos oficiales de RustDesk.supported_distributions,deb_arch_mapynix_system_mapconvierten facts de Ansible en valores utilizables para APT y Nix en Ubuntu y Pop!_OS, incluyendo hosts ARM64.clipboard_manager_package_candidatesdefine qué paquetes cuentan como gestor de portapapeles existente a efectos del modoautode clipboard-history y CopyQ.clipboard_history_branchfija la rama del forkaxellpadilla/clipboard-historydesde la que se descargan los binarios precompilados y los ficheros de sistema (por defectopatched).office_suite_package_candidatesdefine qué paquetes cuentan como suite ofimática existente a efectos del modoautode LibreOffice.gnome_desktop_package_candidatesdefine qué paquetes se consideran evidencia de una sesión GNOME;gnome-tweakssolo se añade cuando esa base existe.gnome_secret_service_packagesdefine qué paquete aporta el backend Secret Service/libsecret para sesiones GNOME.vscode_file_manager_integrationaceptaauto,nautilus,desktop-entryodisabled.virt_manager_packagesdefine los paquetes APT que componen el stack de virtualización local.openvpn_core_packagesdefine la base mínima de OpenVPN.openvpn_network_manager_packagesdefine el backend adicional que solo se instala cuando el modoautodetectanetwork-managero cuando fuerzasfeature_flags.openvpn=enabled.virt_manager_default_uridefine la URI por defecto que usará virt-manager/libvirt en~/.config/libvirt/libvirt.conf.
Para instalar el perfil nativo de NetworkManager con los ajustes de split tunnel y split DNS validados en este host, usa:
sudo ./scripts/nm-openvpn-helper.sh install ~/Documents/farintervpn-final.nmconnection
./scripts/nm-openvpn-helper.sh up farintervpn-finalPara personalizar opciones sin tocar el baseline versionado:
- Copia
ansible/group_vars/all/override.exampleaansible/group_vars/all/override.yml. - El archivo
override.ymlqueda ignorado por Git y Ansible lo cargará automáticamente al ejecutar el playbook.
El modo auto se comporta así:
- Si
nautilusaparece en los facts de paquetes, crea el script en~/.local/share/nautilus/scripts/Open in Code. - Si
nautilusno está instalado, crea~/.local/share/applications/code-open-here.desktopcomo alternativa genérica basada en desktop entry. Esto evita asumir GNOME en Pop!_OS, pero no garantiza un menú contextual nativo en gestores como COSMIC Files.
El modo auto de clipboard_history se comporta así:
- Si ya está instalado
ringboard-server,ringboard-iced,copyqu otro gestor de portapapeles conocido comogpaste,klipper,diodon,cliphist,clipman,xfce4-clipmano un applet de portapapeles para COSMIC, no instala nada adicional. - Si
clip-winestá instalado, lo desinstala automáticamente y migra a Ringboard. - Si no detecta ningún gestor, ejecuta el script oficial
install-with-cargo-systemd.shdel forkaxellpadilla/clipboard-historyconRINGBOARD_CLIENT=iced, que descarga los binarios precompilados, instala los servicios systemd de usuario y arranca el servidor junto con el watcher de sesión. - En COSMIC además precrea la entrada de
Super+Ven el fichero de shortcuts y configuraCOSMIC_DATA_CONTROL_ENABLED=1para el soporte de portapapeles en Wayland; en GNOME/Pop!_OS intenta registrar el custom shortcut víagsettingsy libera tantotoggle-message-traycomotoggle-quick-settingscuando hay una sesión DBus disponible.
El modo legacy de CopyQ se comporta así:
- Si ya está instalado
copyqo algún gestor de portapapeles conocido comogpaste,klipper,diodon,cliphist,clipman,xfce4-clipmano un applet de portapapeles para COSMIC, no instala nada adicional. - Si no detecta ninguno y
feature_flags.clipboard_historyestá endisabled, añadecopyqal conjunto de paquetes base.
En Pop!_OS 24.04 LTS con COSMIC, System76 no anuncia todavía un historial de portapapeles integrado por defecto en la release actual. Sí aparece como trabajo planificado en el roadmap oficial de COSMIC Epoch 2 bajo “COSMIC Clipboard Manager”, así que la detección auto contempla también nombres de paquetes plausibles del ecosistema COSMIC para evitar instalar CopyQ encima cuando esa pieza ya exista en el sistema.
El modo auto de LibreOffice se comporta así:
- Si ya está instalada una suite conocida como
libreoffice,onlyoffice-desktopeditors,calligra,abiwordognumeric, no instala nada adicional. - Si no detecta ninguna, añade
libreofficeal conjunto de paquetes base.
Las herramientas de escritorio GNOME se comportan así:
gnome-tweakssolo se instala cuando el host ya tiene una pila GNOME detectada.- Esto evita meter tooling específico de GNOME en equipos Pop!_OS que no estén usando GNOME/Nautilus como entorno principal.
- Ubuntu y Pop!_OS usan Flatpak para la mayoría de aplicaciones de escritorio de terceros; la selección se resuelve a partir de facts de Ansible y se puede diferenciar por distro sin tocar los roles.
- La instalación de Flatpak comprueba primero qué remotos y aplicaciones existen antes de añadir o instalar nada, para mantener la ejecución repetible.
- RustDesk se instala desde el
.deboficial upstream y no vía Flatpak, porque el servicio nativo de systemd es el camino necesario para acceso pre-login y reinicios limpios del host. - Docker usa
json-filecon rotación, modonon-blockingy buffer acotado para evitar crecimiento descontrolado de logs y reducir bloqueos por I/O, preservando otras claves ya presentes endaemon.jsoncomodata-root. Loslog-optsse escriben como strings porquedockerdlo exige endaemon.json. - Nix usa
nix_install_modepara controlar cómo se instala en el host. El valor por defecto essingle-user, que evita crear la batería de usuariosnixbld*en estaciones de trabajo donde no hace falta el daemon multiusuario. Si necesitas el modelo clásico con daemon y build users compartidos, cambianix_install_modeamulti-user. - En modo
multi-user, el repositorio sigue usando Determinate Systems para simplificar una instalación consistente en Ubuntu/Pop!_OS. - Desde que se retiró Home Manager, el rol
nixsolo instala el binario de Nix; no construye ni activa ningún perfil.nix/flake.nixúnicamente exponedevShells(nil, nixpkgs-fmt, statix) y los checks de lint — úsalo connix developpara un shell de validación, no para gestionar paquetes de usuario. - El rol
shell_configreemplaza lo que antes hacía Home Manager: instala Oh My Zsh (instalador oficial, modo--unattended) y plantea~/.zshrcdesde una plantilla Jinja2 (tema, plugins, autosuggestions/syntax-highlighting vía paquetes APT, alias, variables de sesión y el hook dedirenv). npm/npxno tienen wrapper ni alias hacia Bun: vienen directos del paquetenodejsde NodeSource. Se probaron wrappers hacia Bun paranpm/npx/yarn/pnpm, pero Bun migrapackage-lock.json/pnpm-lock.yaml/yarn.locka su propiobun.lockde forma unidireccional y sin flag para desactivarlo — sorprendía en proyectos existentes, así que se quitaron.- El rol
shell_configtambién instala el timer de usuarioworkstation-auto-clean(plantillas.service/.timeren~/.config/systemd/user/), que limpia periódicamente~/Downloadsy directorios de caché de herramientas (~/.bun/install/cache,~/.cache/cargo-target,~/.cache/go-build,~/.cache/go/pkg/mod), y ejecutauv cache prune,direnv pruneynix-collect-garbage --delete-older-than. direnvahora se instala como paquete APT (antes lo aportaba Home Manager); el hook de Zsh vive en la plantilla deshell_config.- Si una máquina ya tiene Nix multiusuario y quieres eliminar los usuarios
nixbld*, usaansible/nix-migrate-single-user.ymlomake nix-migrate-single-user. Ese flujo desinstala la instalación multiusuario existente con/nix/nix-installer uninstall --no-confirmcuando detecta Determinate, o aplica los pasos documentados por upstream para Linux con systemd cuando no hay receipt/uninstaller, y luego vuelve a aprovisionar Nix en modosingle-user. ansible/nix-clean.yml/make nix-cleanahora solo ejecutanix-collect-garbagegenérico — la poda de generaciones de Home Manager se retiró porque ya no se crean generaciones nuevas.- Warp Terminal se instala desde el repositorio APT oficial (
releases.warp.dev), no desde Flatpak (no publican uno) ni desde Nix.
Si este host todavía tiene una activación de Home Manager de una versión anterior de este repo (perfil en ~/.local/state/nix/profiles/my-workstation-home-manager, el timer workstation-auto-clean instalado por Nix, wrappers de npm/npx/yarn/pnpm enlazados al store, o un ~/.zshrc simbólico hacia /nix/store), ejecuta la limpieza dedicada antes de volver a aplicar el playbook normal:
ansible-playbook ansible/nix-teardown.yml -K
# o
make nix-teardownEsto: detiene y deshabilita el timer/servicio workstation-auto-clean heredado, elimina los wrappers de ~/.local/bin que aún apunten al store, borra el perfil nombrado de Home Manager y las rutas legacy conocidas, restaura .zshrc/.zshenv desde su copia .home-manager-backup si Ansible la había creado, y finalmente ejecuta nix-collect-garbage -d para reclamar el espacio del store. Nix en sí no se desinstala — se mantiene para nix shell/nix develop. Después, vuelve a correr make playbook para que dev_tools, desktop_apps y shell_config aprovisionen lo que Home Manager gestionaba antes.
Si el host ya corrió una versión anterior de este mismo repo (no de Home Manager, sino de cambios internos posteriores: el antiguo CARGO_HOME personalizado en ~/.local/share/cargo, o los wrappers de Bun para npm/npx/yarn/pnpm en ~/.local/bin), usa en cambio make migrate (ansible/migrate.yml) — encadena el teardown de Home Manager con esas limpiezas adicionales, idempotente y seguro de correr sin importar cuáles apliquen.
DOTFILES_REPO_URLenbootstrap.shsi quieres clonar desde un fork o mirror distinto al repositorio oficial.- El tema y los plugins de Oh My Zsh:
oh_my_zsh_themeyoh_my_zsh_pluginsenansible/group_vars/all/main.yml. - La política de limpieza en
ansible/roles/shell_config/templates/workstation-auto-clean.sh.j2y sus variables (workstation_cleanup_*_max_age_days,nix_cleanup_generation_max_age_days) enansible/group_vars/all/main.yml. nodesource_major_versionenansible/group_vars/all/main.ymlsi quieres cambiar la versión mayor de Node.js instalada.nix_install_modeenansible/group_vars/all/main.ymlsi quieres elegir entresingle-userymulti-user. Si una máquina ya tiene Nix multiusuario instalado, el playbook falla de forma explícita cuando pidessingle-userpara que no te quedes con los usuariosnixbld*pensando que el modo cambió solo.DOTFILES_EDITORsi desactivas VS Code y quieres queEDITORyVISUALapunten a otro binario.rustdesk_versionenansible/group_vars/all/main.ymlsi quieres fijar una release específica de RustDesk en lugar delatest.feature_flags.virt_manager,virt_manager_packagesyvirt_manager_default_urisi quieres ajustar el stack de virtualización local.- Los
feature_flags,distro_flatpak_appsy el modo de integración del gestor de archivos enansible/group_vars/all/main.yml. feature_flags.openvpn,openvpn_core_packagesyopenvpn_network_manager_packagessi quieres ajustar cuándo se instala el backend de OpenVPN y evitar dependencias de NetworkManager cuando no hagan falta.
Para aprovisionar solo OpenVPN y sus paquetes relacionados:
ansible-playbook ansible/local.yml --tags openvpn
./bootstrap.sh --tags openvpnPara instalar solo una feature opcional sin tocar override.yml, usa dotfiles_only_features.
El selector fuerza a enabled solo las features indicadas, desactiva el resto de features opcionales durante esa ejecución y evita incluir roles no relacionados. En una ejecución como thunderbird, el playbook ya no recorre desktop_apps, docker, virt_manager, file_manager ni nix, y tampoco instala el bundle por defecto de Flatpaks de escritorio.
Ejemplos:
ansible-playbook ansible/local.yml --extra-vars 'dotfiles_only_features=thunderbird' -K
make install-feature features=thunderbird
./bootstrap.sh --only-feature thunderbirdTambién acepta varias features separadas por comas:
make install-feature features=thunderbird,openvpn
./bootstrap.sh --only-feature thunderbird,openvpnRustDesk queda aprovisionado como paquete nativo y con el servicio rustdesk habilitado en systemd, así que tras volver a ejecutar el playbook no debería hacer falta reiniciar toda la máquina. Si el login manager sigue usando Wayland, el acceso a la pantalla de login puede seguir limitado porque upstream todavía depende de X11 para ese escenario.