Creación de Custom Boxes para Vagrant
Resumen de una línea
Proceso para crear, personalizar y distribuir boxes (imágenes Vagrant) personalizados con tu stack específico, eliminando provision repetitivo.
¿Por Qué Crear Custom Boxes?
Problema: Provisioning Lento
# Sin custom box:
vagrant up
├─ Crea VM (1 min)
├─ apt-get update (3 min)
├─ apt-get install nodejs npm postgresql (5 min)
├─ npm install -g gulp webpack (2 min)
└─ Total: ~11 minutos
# Cada miembro del equipo hace esto diario ❌Solución: Custom Box Preconfigurado
# Con custom box:
vagrant up
└─ Crea VM desde box con todo pre-instalado (1 min)
# Ganancia: Reduce 11 min → 1 min por developer-day ✅Estrategia: Crear un Box
Paso 1: Partir de Base Box Genérica
# Crear directorio para desarrollo del box
mkdir vagrant-nodejs-box && cd vagrant-nodejs-box
# Crear Vagrantfile mínimo
vagrant init generic/ubuntu2004Paso 2: Provisioning Manual (Development)
vagrant up
vagrant sshDentro de la VM:
# 1. Actualizar sistema
sudo apt-get update
sudo apt-get upgrade -y
# 2. Instalar dependencias base
sudo apt-get install -y build-essential curl wget git vim
# 3. Instalar runtime (Node.js)
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
# 4. Instalar servicios (PostgreSQL)
sudo apt-get install -y postgresql postgresql-contrib
# 5. Instalar global tools
sudo npm install -g yarn gulp webpack
# 6. Cleanup (importante para box pequeño)
sudo apt-get clean
sudo apt-get autoclean
sudo apt-get autoremove -y
# Salir
exitPaso 3: Automatizar Provisioning
Crear provision.sh (en host):
#!/bin/bash
set -e
echo "=== Actualizar sistema ==="
sudo apt-get update
sudo apt-get upgrade -y
echo "=== Instalar base ==="
sudo apt-get install -y build-essential curl wget git vim
echo "=== Instalar Node.js ==="
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
echo "=== Instalar PostgreSQL ==="
sudo apt-get install -y postgresql postgresql-contrib
echo "=== Instalar global tools ==="
sudo npm install -g yarn gulp webpack
echo "=== Cleanup ==="
sudo apt-get clean
sudo apt-get autoclean
sudo apt-get autoremove -y
echo "✅ Provisioning completado"Actualizar Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2004"
config.vm.hostname = "nodejs-dev"
config.vm.provision "shell", path: "provision.sh"
config.vm.provider "libvirt" do |libvirt|
libvirt.memory = 2048
libvirt.cpus = 2
end
endUsar para desarrollo:
# Destruir VM anterior (si existe)
vagrant destroy -f
# Levantar con provisioning
vagrant up
# Verificar
vagrant ssh -c "node --version && psql --version"Crear Box desde VM Configurada
Método 1: Packaging Manual (VirtualBox → cualquier provider)
# En el host (después de vagrant up y provisioning):
vagrant halt
# Empaquetar la VM
vagrant package --output nodejs-dev-1.0.box
# Verifica qué se creó
ls -lh nodejs-dev-1.0.box
# -rw-r--r-- 1 user user 1.2G nodejs-dev-1.0.boxResultado: Un archivo .box que contiene:
- Imagen QCOW2 (o VMDK para VirtualBox)
- Vagrantfile plantilla
- Metadatos
Método 2: Desde libvirt (KVM)
# List VMs libvirt
virsh -c qemu:///system list --all
# Obtener ruta del disco
virsh domblklist nodejs-dev
# Convertir QCOW2 → Box
# Box necesita estructura específica
mkdir -p box-contents
cd box-contents
# 1. Copiar imagen
cp /var/lib/libvirt/images/nodejs-dev.qcow2 box.img
# 2. Crear Vagrantfile plantilla
cat > Vagrantfile << 'EOF'
Vagrant.configure("2") do |config|
config.vm.provider "libvirt" do |libvirt|
libvirt.driver = "kvm"
end
end
EOF
# 3. Crear metadata.json
cat > metadata.json << 'EOF'
{
"provider": "libvirt",
"version": "1.0",
"architecture": "x86_64",
"description": "Ubuntu 20.04 con Node.js, PostgreSQL"
}
EOF
# 4. Empaquetar
tar czf ../nodejs-dev-1.0.box ./*
cd ..
ls -lh nodejs-dev-1.0.boxAgregar Box Localmente
# Registrar box en Vagrant
vagrant box add nodejs-dev-local ./nodejs-dev-1.0.box
# Verificar
vagrant box list
# nodejs-dev-local (libvirt, 1.0)Usar en nuevo proyecto:
mkdir mi-proyecto && cd mi-proyecto
vagrant init nodejs-dev-local
# Vagrantfile ahora tiene:
# config.vm.box = "nodejs-dev-local"
vagrant up
# ✅ 1 minuto: VM con Node + PostgreSQL listaDistribuir Boxes (Team / Público)
Opción 1: Almacenamiento Local (Git, NFS)
# Commit a repo privado
git lfs add nodejs-dev-1.0.box # Large File Storage
git commit -m "Add nodejs dev box"
git push
# En otra máquina:
git clone <repo>
vagrant box add nodejs-dev ./nodejs-dev-1.0.boxOpción 2: Vagrant Cloud (Oficial)
# Crear cuenta: https://app.vagrantup.com
# Publicar box
vagrant cloud publish username/nodejs-dev 1.0 libvirt nodejs-dev-1.0.box \
--description "Ubuntu 20.04 con Node.js y PostgreSQL" \
--release
# Otros usuarios lo usan:
vagrant init username/nodejs-dev --minimal
vagrant up
# ✅ Descarga box automáticamenteOpción 3: S3 / Servidor Privado
# Vagrantfile en tu servidor
config.vm.box = "nodejs-dev"
config.vm.box_url = "https://s3.empresa.com/boxes/nodejs-dev-1.0.box"
config.vm.box_download_checksum = "sha256-abc123..."
config.vm.box_download_checksum_type = "sha256"Versionado de Boxes
Estrategia de Versiones
nodejs-dev-1.0.box ← Base: Node 16, PostgreSQL 12
nodejs-dev-1.1.box ← Update: PostgreSQL 13, npm packages actualizados
nodejs-dev-2.0.box ← Major: Node 18, Debian 12, Redis añadido
Usar versiones específicas en Vagrantfile:
config.vm.box = "username/nodejs-dev"
config.vm.box_version = "~> 1.1" # ≥ 1.1, < 2.0Mantener Boxes en Git LFS
# Configurar Git LFS
git lfs install
# Trackear boxes
git lfs track "*.box"
# Commit
git add .gitattributes nodejs-dev-*.box
git commit -m "Add nodejs-dev box v1.0, v1.1, v2.0"
git pushValidación de Boxes
Checklist Antes de Distribuir
# 1. Verificar tamaño
ls -lh nodejs-dev-1.0.box
# ¿< 2GB? ✅ (si > 2GB, limpiar más)
# 2. Probar en máquina diferente
mkdir test-box && cd test-box
vagrant init ../nodejs-dev-1.0.box
vagrant up
vagrant ssh -c "node -v && npm ls -g"
# 3. Verificar provisioning (si lo usas)
vagrant destroy
vagrant up
# ¿Provisioning se ejecuta correctamente? ✅
# 4. Performance
time vagrant up # Debería ser < 2 minutos
time vagrant ssh -c "npm install lodash" # NFS rápido? ✅Troubleshooting
Box muy grande (> 3GB)
# Problema: Muchos archivos temporales
# Solución: Limpiar dentro de la VM antes de package
vagrant ssh
# Limpiar caches
sudo apt-get clean
sudo apt-get autoclean
sudo apt-get autoremove -y
# Limpiar logs
sudo journalctl --vacuum=50M
sudo find /var/log -type f -delete
# Limpiar tmp
sudo rm -rf /tmp/* /var/tmp/*
# Limpiar SSH keys (se regeneran al usar box)
sudo rm -f /etc/ssh/ssh_host_*
# Zerear disco (opcional, mejora compresión)
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY
exit
# Ahora empaquetar
vagrant halt
vagrant package --output nodejs-dev-1.0.boxBox no bootea después de package
# Verificar que Vagrant guest agent está instalado
vagrant ssh
which vagrant
# /usr/bin/vagrant debe existir
# Si no:
wget https://releases.hashicorp.com/vagrant/2.3.0/vagrant_2.3.0_linux_amd64.zip
unzip vagrant_2.3.0_linux_amd64.zip -d /tmp
sudo mv /tmp/vagrant /usr/bin/
exit
vagrant halt
vagrant package --output nodejs-dev-1.0.boxRelaciones
Conecta con
- Vagrant - Introducción y Conceptos Fundamentales — Conceptos de boxes
- Vagrant + libvirt - Configuración Completa de Networking y Almacenamiento — Usar boxes en KVM
- KVM (Kernel-based Virtual Machine) — Backend virtualización
Casos de Uso Relacionados
- CI/CD: Usar custom box en pipelines de testing
- Training: Distribuir box a estudiantes (one-click setup)
- Team: Equipo de desarrollo con ambiente idéntico
- Stack Replicación: Clonar stack completo fácilmente
Conclusión
Custom boxes son la optimización final de Vagrant:
- ✅ Setup reproducible en 1 minuto
- ✅ Código shareable (
Vagrantfile+provision.sh) - ✅ Distribución escalable a equipos
- ✅ Versionado automático
Caso ideal: Crear un box base para cada proyecto/equipo, actualizar anualmente, distribuir vía Git LFS o Vagrant Cloud.