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

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?




¿Te gusta lo que lees? Suscríbete!

Si quieres recibir en tu email antes que nadie las noticias que se cuecen en este blog, sólo tienes que dejar tu dirección de correo electrónico.



Author image
Carlos Azaustre
CTO & Co-Founder @ Chefly. Desarrollador Web y Diseñador Gráfico. Apasionado de la tecnología HTML5 y el mundo JavaScript. Geek, adicto a las series y a las camisetas.