Si desarrollas proyectos web, ya sea para ti solo o con un equipo de varias personas, te habrás dado cuenta que cada desarrollador tiene un entorno y hardware distinto, Unos son usan Windows, otros son más Linux, otros programan en un Macbook… Y entonces surgen las preguntas ¿Cómo instalo Node.js en Windows? ¿Como se instala MongoDB en Mac? Lo ideal será que todos tuviesemos el mismo Sistema Operativo y con todo lo necesario instalado ¿Verdad? Pues eso y mucho más es posible
con Vagrant, veamos como.
Vagrant es un sistema que funciona sobre Virtual Box, un software que sirve para instalar máquinas virtuales con otros Sistemas Operativos en tu máquina. Lo malo de Virtual Box era que si te instalabas un Linux y querias usar un software específico tenías que entrar dentro de el, reservar disco duro, memoria, etc… Ahora hay programas como Parallels para Mac que eso te lo facilitan, pero aun así no llegan a lo que Vagrant nos ofrece.
Vagrant te descarga una sola vez una imagen de Linux que puedes replicar para cada uno de los proyectos que desees que tengan configuraciones diferentes. Imaginemos que tenemos un proyecto que usa Django y PostgreSQL y otro que usa Node y MongoDB, con Vagrant tendríamos una única instancia de Linux corriendo por debajo en nuestra máquina y 2 entornos diferentes que usarán esa misma máquina pero con configuraciones y variables de entorno diferentes para cada proyecto. It is cool, baby!
¿Y cómo lo hacemos? pues muy sencillo, el primer paso es descargarse Virtual Box para el sistema operativo de tu máquina. En mi caso tengo un MacBook Pro con OS X Mavericks, por lo que descargo el VirtualBox 4.3.6 for OS X hosts.
Después tengo que descargar Vagrant, de nuevo como uso Mac me descargo el de OS X.
Con todo esto, ya empezamos a preparar lo que será el entorno de nuestro proyecto. Nos dirigimos al terminal (el terminal es nuestro amigo aunque no seamos Linux Rockstars) y vamos a una carpeta donde vayamos a desarrollar nuestro proyecto y ejecutamos:
$ vagrant init
Este nos creará un fichero Vagrantfile
donde le indicaremos que ha de configurar en nuestra máquina virtual. El que he creado yo para montarme un entorno MEAN es el siguiente:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
config.vm.synced_folder "project/", "/project/"
config.vm.network :forwarded_port, guest: 3000, host: 3000
config.vm.provision :shell, :path => "env/bootstrap/local.sh"
end
Aquí estoy indicando que use una imagen de Linux de VirtualBox llamada precise64
y la URL de donde puede descargarla. También le indico que carpetas quiero que me sincronice en local con la máquina virtual, en este caso tendrá todo el código de mi proyecto en una carpeta project
en mi entorno local, pudiendo usar Sublime Text o cualquier otro editor o IDE con el que nos sintamos cómodos, y todo lo que modifiquemos se modificará automáticamente en la carpeta /project
de la maquina virtual linux que nos hemos creado. Tambien le indico que el puerto 3000 de la maquina virtual (guest) se relacione con el 3000 de mi local (host) de esa forma puedo usar el navegador local para correr los proyectos que se ejecutan en la máquina virtual usando el mismo puerto.
Y por último con el comando config.vm.provision
le indico la ruta de un script en bash con los comandos que instalarán en Linux todas las dependencias y software que necesitamos para crear nuestro entorno.
La estructura de carpetas y archivos de configuración será la siguiente:
- Vagrantfile
- env/
- bootstrap/
# Archivo principal del setup desde aqui llamamos otros
- local.sh
- build/
# Scripts que instalan los paquetes y dependencias que necesitemos
# ordenados por tipo y tecnologÃa
- deps.sh
- dotfiles.sh
- git.sh
- mongo.sh
- node.sh
- redis.sh
- settings/
# Variables de entorno (NODE_ENV, Api Keys, contraseñas, etc...)
- local.sh
- project
# Carpeta donde está todo el código de nuestro proyecto
Por ejemplo el script node.sh tiene estos comandos:
#!/bin/bash
# Check if node is installed
type node >/dev/null 2>&1 && NODE_INSTALL=false || NODE_INSTALL=true
# Install node
if $NODE_INSTALL; then
echo ""
echo "[mean_vagrant] INSTALLING Node.js"
echo ""
# sudo apt-get update
apt-get -q update
apt-get install -y python-software-properties python g++ make
apt-get -q update
add-apt-repository ppa:chris-lea/node.js
apt-get -q update
apt-get install -y nodejs
npm install -g express
npm install -g bower
npm install -g stylus
npm install -g grunt
npm install -g grunt-cli
npm install -g forever
npm install -g nodemon
fi
Puedes ver el resto de estos archivos en este repositorio en Github.
¿Y como pongo todo esto en marcha? pues con el comando:
$ vagrant up
Esto llevará un rato mientras se descarga la imagen .box
de Linux si es la primera vez, y ejecuta todas las instalaciones que hemos indicado en los scripts.
Una vez hecho esto, podemos entrar por SSH en la máquina virtual con el comando:
$ vagrant ssh
Y si navegamos hasta cd /project
veremos que tenemos los mismos ficheros que en nuestra carpeta local project. Ahora si ejecutamos grunt, node server.js, mongo, etc… lo tenemos que hacer desde la máquina virtual mientras que el código lo podemos editar desde el entorno local porque será replicado al virtual, tomando de el toda su configuración. Si usas Grunt, nodemon y otras tantos recursos para automatizar tareas, no te darás ni cuenta de que estás ejecutando tu proyecto en una máquina virtual.
Para parar la máquina virtual tienes el comando
$ vagrant halt
Puedes también suspenderla con
$ vagrant suspend
Para volver a iniciarla
$ vagrant up
y para reiniciarla si ya la tienes corriendo
$ vagrant reload
Y si la quieres eliminar del todo porque no la necesitas, tienes el comando:
$ vagrant destroy
Creo que esta herramienta es muy útil y cada vez va a ser más usada, viene a ser para los entornos de desarrollo el cambio que supuso Git para el control de versiones. ¿Qué te parece a ti?