Vagrant es una herramienta para crear y gestionar entornos de máquinas virtuales en un flujo de trabajo unificado. Si alguna vez has pasado horas configurando un entorno de desarrollo solo para escuchar “en mi máquina funciona” de un compañero, Vagrant resuelve ese problema. Defines todo tu entorno en un único archivo — el Vagrantfile — y cualquier persona del equipo puede levantar una configuración idéntica con un solo comando.

Esta guía cubre la instalación de Vagrant, la configuración del Vagrantfile, estrategias de provisioning, redes, entornos multi-máquina y flujos de trabajo que mantienen los entornos de desarrollo consistentes en todo tu equipo.

Requisitos Previos

  • Un procesador de 64 bits con virtualización por hardware habilitada (VT-x/AMD-V)
  • Al menos 8 GB de RAM (4 GB para el host, 4 GB para las VMs)
  • VirtualBox instalado (u otro proveedor compatible)
  • Experiencia básica con la línea de comandos
  • Git instalado (para compartir Vagrantfiles)

Instalar Vagrant y Tu Primera VM

Instala Vagrant desde la página oficial de descargas. Evita las versiones de gestores de paquetes — suelen estar desactualizadas.

# Verificar la instalación
vagrant --version

# Inicializar un nuevo proyecto con Ubuntu 22.04
mkdir my-project && cd my-project
vagrant init ubuntu/jammy64

# Arrancar la VM
vagrant up

# Conectarse por SSH
vagrant ssh

El primer vagrant up descarga la imagen del box (una plantilla de VM preconfigurada) y crea una máquina virtual. Las ejecuciones posteriores arrancan en segundos porque la imagen queda en caché local.

Comandos Esenciales de Vagrant

vagrant up          # Crear e iniciar la VM
vagrant ssh         # Conectarse por SSH a la VM en ejecución
vagrant halt        # Apagar la VM de forma controlada
vagrant reload      # Reiniciar la VM (aplica cambios del Vagrantfile)
vagrant destroy     # Eliminar la VM por completo
vagrant status      # Ver el estado de la VM
vagrant provision   # Volver a ejecutar los scripts de provisioning
vagrant snapshot save <name>    # Guardar el estado de la VM
vagrant snapshot restore <name> # Restaurar a un estado guardado

Configuración Avanzada del Vagrantfile

El Vagrantfile es código Ruby que define la configuración de tu VM. Este es un ejemplo listo para producción:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/jammy64"
  config.vm.hostname = "dev-server"

  # Configuración de red
  config.vm.network "private_network", ip: "192.168.56.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "forwarded_port", guest: 3000, host: 3000

  # Carpeta sincronizada (host -> guest)
  config.vm.synced_folder "./src", "/var/www/app",
    owner: "www-data", group: "www-data"

  # Configuración específica del proveedor
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
    vb.name = "dev-server"
    # Habilitar virtualización anidada
    vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
  end

  # Provisioning con shell
  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y nginx nodejs npm
    systemctl enable nginx
  SHELL
end

Modos de Red

Vagrant soporta tres modos de red:

ModoCaso de UsoAcceso
Puerto RedirigidoExponer puertos específicos del guest al hostlocalhost:8080 → guest:80
Red PrivadaComunicación entre VMs en red solo para el host192.168.56.10 desde el host y otras VMs
Red PúblicaPuente a la red físicaLa VM obtiene una IP de LAN, accesible por otras máquinas

Para desarrollo, las redes privadas son la opción más segura. Permiten la comunicación entre VMs sin exponer los servicios a la red externa.

Estrategias de Provisioning

Vagrant soporta múltiples métodos de provisioning. Elige según las herramientas de tu equipo:

Provisioner Shell (Sencillo)

config.vm.provision "shell", path: "scripts/setup.sh"

Provisioner Ansible (Recomendado para Equipos)

config.vm.provision "ansible" do |ansible|
  ansible.playbook = "provisioning/playbook.yml"
  ansible.inventory_path = "provisioning/inventory"
  ansible.become = true
end

Provisioner Docker

config.vm.provision "docker" do |d|
  d.pull_images "nginx"
  d.pull_images "postgres:15"
  d.run "nginx", args: "-p 80:80"
end

Escenario real: Tienes un equipo de 8 desarrolladores trabajando en una aplicación web que requiere PostgreSQL, Redis, Nginx y Node.js. En lugar de que cada desarrollador instale todo manualmente (y termine con versiones distintas), creas un Vagrantfile con provisioning Ansible. Un desarrollador nuevo clona el repositorio, ejecuta vagrant up y tiene un entorno funcional en 10 minutos. Cuando actualizas PostgreSQL de 14 a 15, actualizas el playbook y todos reciben el cambio en su próximo vagrant provision.

Entornos Multi-Máquina

Vagrant destaca en la simulación local de arquitecturas de producción. Define múltiples VMs en un solo Vagrantfile:

Vagrant.configure("2") do |config|
  # Servidor web
  config.vm.define "web" do |web|
    web.vm.box = "ubuntu/jammy64"
    web.vm.hostname = "web-server"
    web.vm.network "private_network", ip: "192.168.56.10"
    web.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
    end
    web.vm.provision "shell", inline: <<-SHELL
      apt-get update && apt-get install -y nginx
    SHELL
  end

  # Servidor de base de datos
  config.vm.define "db" do |db|
    db.vm.box = "ubuntu/jammy64"
    db.vm.hostname = "db-server"
    db.vm.network "private_network", ip: "192.168.56.11"
    db.vm.provider "virtualbox" do |vb|
      vb.memory = "2048"
    end
    db.vm.provision "shell", inline: <<-SHELL
      apt-get update && apt-get install -y postgresql
    SHELL
  end

  # Servidor de caché
  config.vm.define "cache" do |cache|
    cache.vm.box = "ubuntu/jammy64"
    cache.vm.hostname = "cache-server"
    cache.vm.network "private_network", ip: "192.168.56.12"
    cache.vm.provision "shell", inline: <<-SHELL
      apt-get update && apt-get install -y redis-server
      sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' /etc/redis/redis.conf
      systemctl restart redis
    SHELL
  end
end

Inicia máquinas concretas o todas a la vez:

vagrant up web      # Iniciar solo el servidor web
vagrant up          # Iniciar todas las máquinas
vagrant ssh db      # Conectarse por SSH al servidor de base de datos

Comparativa: Vagrant vs Alternativas

CaracterísticaVagrantDockerMultipassNix/devenv
AislamientoVM completa (SO íntegro)Contenedor (kernel compartido)VM ligeraA nivel de proceso
Tiempo de Arranque30-120 segundos1-5 segundos10-30 segundosInstantáneo
Uso de RecursosAlto (SO completo por VM)Bajo (kernel compartido)MedioMínimo
Multi-SOSí (cualquier SO en cualquier host)Solo contenedores Linux*Solo UbuntuLinux/macOS
ProvisioningShell, Ansible, Chef, PuppetDockerfileCloud-initExpresiones Nix
Simulación de RedExcelente (multi-máquina)Buena (redes Docker)BásicaN/A
Paridad con ProducciónAltaMuy altaMediaBaja
Curva de AprendizajeBajaMediaBajaAlta

*Docker Desktop ejecuta una VM Linux en macOS/Windows, por lo que los contenedores siguen siendo Linux.

Cuándo elegir Vagrant: pruebas con SO completo, arquitecturas multi-máquina, desarrollo multiplataforma Windows/Linux o cuando tu entorno de producción usa VMs en lugar de contenedores.

Errores Comunes y Casos Especiales

  • Rendimiento de carpetas sincronizadas en macOS/Windows: Las carpetas compartidas de VirtualBox son notoriamente lentas con bases de código grandes. Usa NFS (type: "nfs") en macOS/Linux o SMB en Windows. Para el mejor rendimiento, utiliza el tipo rsync con vagrant rsync-auto.

  • Fijar la versión del box: Fija siempre la versión del box en el Vagrantfile (config.vm.box_version = "20231215.0.0"). Los boxes sin versión fija se actualizan automáticamente y pueden romper los scripts de provisioning.

  • Asignación de memoria: VirtualBox reserva la memoria al arrancar, no bajo demanda. Si asignas 4 GB a una VM que consume 512 MB en reposo, igualmente pierdes 4 GB del host. Dimensiona las VMs con criterio.

  • Conflictos de puertos: Si el puerto 8080 ya está en uso en el host, vagrant up falla. Usa auto_correct: true en los puertos redirigidos para que Vagrant elija automáticamente un puerto disponible.

  • Vagrant y WSL2: Ejecutar Vagrant dentro de WSL2 requiere configuración adicional. Define VAGRANT_WSL_ENABLE_WINDOWS_ACCESS=1 y asegúrate de que VirtualBox esté instalado en Windows, no dentro de WSL.

  • Exportaciones NFS obsoletas: En macOS, un vagrant destroy fallido puede dejar exportaciones NFS obsoletas en /etc/exports. Límpialas con sudo sed -i '' '/# VAGRANT/d' /etc/exports.

Solución de Problemas

ProblemaCausaSolución
vagrant up se queda colgado en “Waiting for machine to boot”VT-x/AMD-V deshabilitado en la BIOSHabilita la virtualización en la configuración de la BIOS
Timeout en la conexión SSHConfiguración de red incorrectaRevisa config.vm.network, prueba con vagrant reload
La carpeta sincronizada no se actualizaGuest Additions de VirtualBox desactualizadasInstala el plugin vagrant-vbguest: vagrant plugin install vagrant-vbguest
”The box could not be found”Nombre del box incorrecto o box privadoVerifica el nombre en Vagrant Cloud
El provisioning falla a mitadError en el script o dependencia faltanteCorrige el script y ejecuta vagrant provision (los scripts idempotentes ayudan)

Resumen

  • Vagrant crea entornos de desarrollo reproducibles definidos en un solo Vagrantfile, eliminando el problema de “en mi máquina funciona”
  • El provisioning con scripts shell, Ansible o Docker automatiza toda la instalación de software dentro de las VMs
  • Los entornos multi-máquina simulan arquitecturas de producción localmente con servidores web, de base de datos y de caché independientes
  • Las redes privadas proporcionan comunicación segura entre VMs sin exponer los servicios al exterior
  • Fija las versiones del box y usa carpetas sincronizadas NFS para evitar las dos frustraciones más comunes con Vagrant
  • Elige Vagrant sobre Docker cuando necesites aislamiento completo del SO, pruebas multi-SO o paridad con producción basada en VMs

Artículos Relacionados