Vagrant es una herramienta de HashiCorp que crea máquinas virtuales de desarrollo a partir de un archivo de texto, el Vagrantfile. Cualquier miembro del equipo que clone el repositorio obtiene la misma máquina con un solo comando, vagrant up, en lugar de seguir un documento de instalación a mano. En este tutorial instalarás Vagrant y VirtualBox en Ubuntu 24.04, crearás una máquina con red, carpeta compartida y aprovisionamiento por script, y después un entorno de dos máquinas (servidor web y base de datos) conectadas por una red privada.

Requisitos previos

Para seguir esta guía necesitas:

  • Un equipo con Ubuntu 24.04 LTS de 64 bits (x86_64) y un usuario con privilegios sudo. Vagrant está pensado para tu equipo de trabajo, no para un servidor remoto: VirtualBox necesita virtualización por hardware y la mayoría de VPS no la exponen.
  • Virtualización por hardware (Intel VT-x o AMD-V) activada en la BIOS.
  • Al menos 8 GB de RAM y 20 GB libres en disco para dos máquinas virtuales.

Paso 1: Instalar VirtualBox

Vagrant no virtualiza por sí mismo: delega en un proveedor. VirtualBox es el que funciona sin plugins adicionales. Instálalo desde los repositorios de Ubuntu:

sudo apt update
sudo apt install virtualbox

El paquete compila el módulo del kernel con DKMS durante la instalación. Comprueba que está cargado:

VBoxManage --version
lsmod | grep vboxdrv
7.0.16_Ubuntur162802
vboxdrv               696320  2 vboxnetadp,vboxnetflt

Paso 2: Instalar Vagrant

La versión de Vagrant en los repositorios de Ubuntu está desactualizada, así que usa el repositorio oficial de HashiCorp. Descarga la clave:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/hashicorp-archive-keyring.gpg

Añade el repositorio:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(. /etc/os-release && echo "$VERSION_CODENAME") main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

Instala Vagrant:

sudo apt update
sudo apt install vagrant

Comprueba la versión:

vagrant --version
Vagrant 2.4.9

Paso 3: Crear el primer Vagrantfile

Vagrant parte de una box, una imagen base preparada para un proveedor. Esta guía usa bento/ubuntu-24.04, mantenida por el proyecto Bento de Chef, que incluye las Guest Additions de VirtualBox necesarias para las carpetas compartidas.

Crea el directorio del proyecto y una carpeta con la aplicación que servirá la máquina:

mkdir -p ~/vagrant-dev/app && cd ~/vagrant-dev
echo '<h1>Servido desde Vagrant</h1>' > app/index.html

Crea el Vagrantfile:

nano Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"
  config.vm.hostname = "dev"

  # Puerto 80 de la máquina accesible en http://localhost:8080 del host
  config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  # Carpeta del proyecto montada dentro de la máquina
  config.vm.synced_folder "./app", "/var/www/app"

  config.vm.provider "virtualbox" do |vb|
    vb.name   = "vagrant-dev"
    vb.memory = 2048
    vb.cpus   = 2
  end

  config.vm.provision "shell", path: "provision.sh"
end

Qué hace cada línea:

  • config.vm.box: la imagen base. Vagrant la descarga la primera vez y la reutiliza en todos tus proyectos.
  • forwarded_port: redirige el puerto 8080 del host al 80 de la máquina. host_ip: "127.0.0.1" evita que quede expuesto al resto de tu red.
  • synced_folder: monta ./app del host en /var/www/app de la máquina. Editas el código con tu editor habitual y la máquina ve los cambios al momento. Por defecto, además, el directorio del proyecto se monta en /vagrant.
  • provider "virtualbox": recursos de la máquina virtual.
  • provision "shell": script que Vagrant ejecuta como root la primera vez que crea la máquina.

Paso 4: Escribir el script de aprovisionamiento

El script instala Nginx y lo apunta a la carpeta compartida. Debe poder ejecutarse varias veces sin romper nada, porque lo relanzarás cada vez que cambies la configuración:

nano provision.sh
#!/usr/bin/env bash
set -euo pipefail

export DEBIAN_FRONTEND=noninteractive

apt-get update
apt-get install -y nginx

cat > /etc/nginx/sites-available/app <<'EOF'
server {
    listen 80 default_server;
    root /var/www/app;
    index index.html;
    sendfile off;
}
EOF

ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
rm -f /etc/nginx/sites-enabled/default

nginx -t
systemctl reload nginx

sendfile off evita que Nginx sirva versiones antiguas de los archivos, un problema conocido con las carpetas compartidas de VirtualBox.

Comprueba que el Vagrantfile no tiene errores de sintaxis:

vagrant validate
Vagrantfile validated successfully.

Paso 5: Levantar la máquina y comprobarla

Crea y arranca la máquina. La primera vez descarga la box (alrededor de 1 GB), así que tardará unos minutos:

vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/ubuntu-24.04' could not be found. Attempting to find and install...
==> default: Importing base box 'bento/ubuntu-24.04'...
==> default: Forwarding ports...
    default: 80 (guest) => 8080 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Mounting shared folders...
    default: /var/www/app => /home/tu_usuario/vagrant-dev/app
==> default: Running provisioner: shell...
    default: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

Comprueba desde el host que la página se sirve a través del puerto redirigido:

curl -s http://localhost:8080
<h1>Servido desde Vagrant</h1>

Edita app/index.html en el host y repite el curl: verás el cambio sin tocar la máquina.

Entra en la máquina por SSH. Vagrant gestiona la clave por ti:

vagrant ssh

Dentro, comprueba el montaje y sal con exit:

df -h /var/www/app
Filesystem      Size  Used Avail Use% Mounted on
var_www_app     468G  120G  348G  26% /var/www/app

Paso 6: Gestionar el ciclo de vida

Estos son los comandos que usarás a diario desde el directorio del proyecto:

ComandoQué hace
vagrant statusEstado de las máquinas del proyecto
vagrant haltApaga la máquina conservando el disco
vagrant upArranca la máquina (sin reaprovisionar si ya existía)
vagrant reloadReinicia aplicando cambios del Vagrantfile (red, recursos, carpetas)
vagrant provisionVuelve a ejecutar los aprovisionadores en una máquina encendida
vagrant reload --provisionReinicia y reaprovisiona
vagrant snapshot save limpioGuarda una instantánea llamada limpio
vagrant snapshot restore limpioVuelve a esa instantánea
vagrant destroy -fBorra la máquina y su disco

Por ejemplo, tras cambiar provision.sh:

vagrant provision

Y para ver el estado:

vagrant status
Current machine states:

default                   running (virtualbox)

Añade .vagrant/ a tu .gitignore: contiene el estado local de las máquinas y las claves SSH generadas, y no debe versionarse. El Vagrantfile y provision.sh sí van al repositorio.

Paso 7: Crear un entorno con varias máquinas

Un mismo Vagrantfile puede definir varias máquinas. Aquí se añade una segunda con MariaDB, conectada al servidor web por una red privada solo accesible entre las máquinas y el host. Destruye antes la máquina anterior para liberar el puerto:

vagrant destroy -f

Sustituye el Vagrantfile:

nano Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = 1024
    vb.cpus   = 1
  end

  config.vm.define "db" do |db|
    db.vm.hostname = "db"
    db.vm.network "private_network", ip: "192.168.56.11"
    db.vm.provision "shell", path: "provision-db.sh"
  end

  config.vm.define "web", primary: true do |web|
    web.vm.hostname = "web"
    web.vm.network "private_network", ip: "192.168.56.10"
    web.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
    web.vm.synced_folder "./app", "/var/www/app"
    web.vm.provision "shell", path: "provision.sh"
    web.vm.provision "shell", inline: "apt-get install -y mariadb-client"
  end
end

Las máquinas se crean en el orden en que aparecen, así que db está lista antes que web. La red 192.168.56.0/21 es el rango que VirtualBox permite por defecto para redes host-only. primary: true hace que vagrant ssh sin argumentos entre en web.

Crea el script de la base de datos. Escucha en la IP privada y crea un usuario al que solo puede conectarse web. Sustituye tu_contraseña_segura por una contraseña propia:

nano provision-db.sh
#!/usr/bin/env bash
set -euo pipefail

export DEBIAN_FRONTEND=noninteractive

apt-get update
apt-get install -y mariadb-server

cat > /etc/mysql/mariadb.conf.d/60-vagrant.cnf <<'EOF'
[mysqld]
bind-address = 192.168.56.11
EOF

systemctl restart mariadb

mariadb <<'SQL'
CREATE DATABASE IF NOT EXISTS app;
CREATE USER IF NOT EXISTS 'app'@'192.168.56.10' IDENTIFIED BY 'tu_contraseña_segura';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'192.168.56.10';
FLUSH PRIVILEGES;
SQL

Levanta el entorno completo:

vagrant up

Comprueba ambas máquinas:

vagrant status
Current machine states:

db                        running (virtualbox)
web                       running (virtualbox)

Prueba la conexión a la base de datos desde web:

vagrant ssh web -c "mariadb -h 192.168.56.11 -u app -p'tu_contraseña_segura' -e 'SHOW DATABASES;'"
+--------------------+
| Database           |
+--------------------+
| app                |
| information_schema |
+--------------------+

Todos los comandos de la tabla anterior aceptan el nombre de una máquina, por ejemplo vagrant halt db o vagrant provision web.

Paso 8: Mantener las boxes

Las boxes se guardan en ~/.vagrant.d/boxes y ocupan espacio. Lista las que tienes:

vagrant box list
bento/ubuntu-24.04 (virtualbox, 202508.03.0, (amd64))

Comprueba si hay versiones nuevas y descárgalas. Las máquinas existentes siguen usando la versión con la que se crearon hasta que las destruyes y recreas:

vagrant box outdated
vagrant box update

Borra las versiones antiguas que ya no usa ninguna máquina:

vagrant box prune

Solución de problemas

VT-x is not available o AMD-V is disabled in the BIOS: la virtualización por hardware está desactivada. Actívala en la BIOS o UEFI del equipo.

The vboxdrv kernel module is not loaded: el módulo no se compiló o no está firmado. Con Secure Boot, completa el registro MOK descrito en el paso 1. Si actualizaste el kernel, reinstala con sudo apt install --reinstall virtualbox-dkms.

The IP address configured for the host-only network is not within the allowed ranges: la IP de private_network está fuera de 192.168.56.0/21. Usa una IP de ese rango o declara los rangos permitidos en /etc/vbox/networks.conf.

Vagrant cannot forward the specified ports on this VM: otro proceso o máquina usa el puerto 8080 del host. Cambia host: o añade auto_correct: true a la línea forwarded_port.

mount: unknown filesystem type 'vboxsf': la box no tiene Guest Additions. Usa una box que las incluya, como las de bento.

Conclusión

Tienes Vagrant y VirtualBox instalados, un entorno de desarrollo con puertos redirigidos, carpeta compartida y aprovisionamiento reproducible, y un segundo entorno con servidor web y base de datos en red privada. Como siguientes pasos, sube el Vagrantfile y los scripts al repositorio de tu proyecto, sustituye los scripts por el aprovisionador ansible_local cuando la configuración crezca, y crea tus propias boxes con Packer para arrancar desde una imagen ya preparada.