Esta semana un compañero me vino a preguntar si conocía alguna forma de poder compilar el software que hacemos en Bitbrain en diferentes plataformas de forma sencilla y rápida. Me comentó que estaba pensando en montar algo con Docker para levantar las máquinas necesarias, poder compilar y eliminarlas con facilidad de nuevo, pero que eso iba a llevar tiempo y necesitaba una solución más a corto plazo.

La verdad es que la "containerización" es probablemente la mejor forma de llevar a cabo estas tareas, en términos de tiempos y eficiencia. Pero también tiene implicaciones de costes y mantenimiento y, aunque es una solución a la que queremos llegar eventualmente, no es ahora mismo una necesidad o una prioridad para nosotros. Además, ninguno somos unos expertos en la materia, por lo que también nos acarrearía un coste de desarrollo adicional que por el momento no necesitamos atacar.

Aunque la oportunidad para aprender e implantar algo así es realmente buena, como he dicho mi compañero estaba buscando una solución más a corto plazo, así que le enseñé Vagrant. No lo conocía, pero le conté un poco como funcionaba en cinco minutos (literal) y se puso a ello. Al día siguiente me vino a comentar que realmente la solución le gustó mucho y que funcionaba genial.

Este episodio me dió que pensar. Casi todos los desarrolladores/programadores hoy en día saben qué es la virtualización y han trabajado alguna vez con ella. Pero mucho no la utilizan porque si la usas a pelo (por ejemplo levantando máquinas virtuales en VirtualBox), es bastante cargante. Tienes que configurar y levantar la máquina, instalar el Sistema Operativo y luego ponerte a instalar todo el software que necesitas para el desarrollo.

En mi día a día, me encuentro a mucha gente que no conoce herramientas como Vagrant, Docker, Kubernetes y muchas otras que hacen que trabajar con máquinas virtuales sea muy sencillo y eficiente.

Lo que viene a continuación es una pequeña introducción al mundo de las máquinas virtuales, de una forma muy sencilla y rápida gracias a Vagrant. Hay muchísimo más por explorar y aprender, pero esto os puede servir como puerta de entrada.

¿Por qué máquinas virtuales?

Imagina que trabajas en Windows y quieres hacer un desarrollo web en PHP. Para poder hacerlo, necesitas montarte un entorno con todo el software necesario para que puedas trabajar.

Lo primero que puede venirte a la cabeza es instalar un WAMP o un XAMPP y a correr. Es una opción perfectamente válida, aunque a mi, personalmente, no me guste nada por varias razones.

No voy a discutir aquí si puedes desarrollar en Windows y desplegar en Linux. Puedes, pero son dos entornos salvajemente distintos y es bastante probable que te encuentres más de un problema y más de dos. Generalmente, en desarrollo web, lo ideal es que la máquina donde desarrolles tenga las mismas características que la máquina donde vas a hospedar la web (SO, versiones de software, configuraciones, etc...).

Para conseguirlo tienes básicamente dos opciones:

  1. Te haces una partición en el disco duro y te instalas la versión de Linux que necesites, te la configuras, te instalas todo el software de desarrollo et voilá: Tienes dos sistemas operativos en un PC.
  2. Te instalas VirtualBox, te levantas una máquina virtual, te instalas la versión de Linux que necesites, te la configuras, te instalas todo el software de desarrollo et voilá: Tienes un sistema operativo dentro de otro.

La versión 1 es un auténtico tostonazo.  Además de toda la complicación de tener un Arranque Dual (Dual Boot) en el ordenador y tener que gestionar particiones del disco duro, al final acabáis con medio disco duro desaprovechado porque o bien trabajáis en un SO, o bien trabajáis en otro. No lo hagáis. La vida merece ser vivida y esto os va a quitar años de salud.

La versión 2 es muy parecida, pero tiene muchas ventajas. Primero de todo, tu sistema operativo principal (Windows en nuestro ejemplo) hace de anfitrión. En tu ordenador tienes eso instalado solamente. Ese SO anfitrión comparte su hardware a través de un software de virtualización (VirtualBox) al sistema operativo huésped, que en nuestro caso será el Linux.

Esquema ubersencillo de virtualización

La primera ventaja de esto es que solo tienes un sistema operativo instalado en tu ordenador. No necesitas particiones, no necesitas Arranque Dual y en general la vida es más hermosa, entra sol por la ventana y la comida te sabe mejor.

La segunda ventaja es que el sistema operativo huésped puedes eliminarlo y volverlo a levantar las veces que sea necesario. También puedes levantar una segunda máquina virtual, una tercera, una cuarta y las que necesites.

Básicamente lo que hace VirtualBox es crear un ordenador ficticio dentro de windows donde puedes instalar otro Windows o un Linux o el SO que quieras. Ese ordenador ficticio usará la CPU, la memoria y el resto de recursos de tu ordenador real a través de VirtualBox.

Windowsception

Y ahora me dices: "Pero Dani, sigo teniendo que configurar la máquina virtual, instalar el sistema operativo y luego todo el stack de software!"

No. No tienes por qué. Otros ya lo han hecho por ti. La última de las ventajas de la virtualización es que puedes exportar e importar máquinas virtuales. Literalmente puedo instalar mi máquina virtual, ponerle todo el software, exportarla y dártela. Luego te la importas en tu VirtualBox, la arrancas y tienes exactamente todo lo que yo puse.

Y aquí entra Vagrant.

¿Qué es Vagrant, me preguntas mientras clavas en mi pupila tu pupila azul?

Vagrant es una tecnología para facilitar el despliegue de máquinas virtuales para desarrollo.

En lo más básico, Vagrant es una capa de software, escrita en Ruby, que te permite gestionar máquinas virtuales de forma eficiente. La principal característica de Vagrant es que funciona por linea de comandos. Tienes que crear un archivo de configuración llamado "Vagrantfile". Luego accedes por linea de comandos (Terminal, PowerShell, CMD...) al directorio donde está ese archivo, escribes "vagrant up", le das al enter y la magia sucede. Se te crea una máquina virtual.

No solo eso, sino que si compartes el archivo Vagrant (y probablemente algo más que hablaremos luego) con tus compañeros de trabajo, solamente necesitan copiar ese archivo, acceder al directorio de la copia, escribir "vagrant up", darle al enter y de nuevo, la misma máquina virtual se levanta.

Existen otros comandos como "vagrant destroy" para borrar una máquina virtual, "vagrant ssh" para conectarte a una máquina virtual en marcha, etc...

Pero esto solo es una pieza del puzzle. Si eso fuera todo lo que ofrece, la verdad es que Vagrant no te aportaría mucho más de lo que te aporta VirtualBox en su interfaz gráfica.

La verdadera potencia de Vagrant radica en las "boxes". Las boxes son preinstalaciones de máquinas virtuales. Lo bueno de vagrant es que puedes crear tus propias "boxes" y compartirlas, con lo cual puedes personalizar ese sistema operativo de desarrollo a tu gusto y utilizarlo en tu empresa para que todos trabajéis con las mismas herramientas.

Crear boxes de vagrant es genial, pero mejor que eso es poder acudir a Vagrant Cloud. En Vagrant Cloud puedes encontrar cientos y cientos de boxes hechas por otra gente que vienen con sistemas operativos instalados de base y te permiten ahorrar mucho tiempo en instalaciones y despliegues de nuevas máquinas.

Digamos que tu servidor de producción tiene Ubuntu 18.04 y quieres montar una máquina virtual con Apache, MySQL y PHP. Sin problemas, buscas un poquito y encuentras por ejemplo esta máquina virtual que lleva Apache 2.4, PHP 7.2 y MySQL 5.7.

Eso sí, aunque el concepto es maravilloso, hay que ir con cuidado. Estas máquina han sido creadas y compartidas por la comunidad. Te puedes encontrar con máquinas virtuales que tengan errores, versiones viejas y toda índole de problemas. Lo bueno es que levantar y probar una máquina es muy rápido y si no te gusta, destruirla también lo es.

Por otra parte, muchas distribuciones de Linux ofrecen de forma oficial boxes con instalaciones básicas de sus sistemas operativos, como Ubuntu o Centos. Yo suelo coger una de esas e instalarle luego el software que necesito como Apache/Nginx, MySQL/MongoDB, PHP, NodeJS... Lo que necesite.

Predicando con el ejemplo

Por ejemplo, si necesito un entorno de desarrollo de Ubuntu, suelo montarlo de la siguiente forma.

Primero de todo me creo un directorio donde estará mi entorno de desarrollo. Luego accedo a ella por PowerShell y escribo el siguiente comando:

$> vagrant init ubuntu/bionic64

Este comando me crea un nuevo archivo Vagrantfile en el directorio que es muy sencillo: simplemente especifica qué box estoy usando por defecto. Suelo añadirle al menos dos cosas: Una IP para poder conectarme por SSH desde una terminal PuTTY y le incremento la memoria RAM al menos a 2GB. Mi Vagrantfile suele quedar más o menos así:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.box = "ubuntu/bionic64"

  config.vm.network "private_network", ip: "192.168.44.44"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "4096"
  end
end

Puedes crear directamente este Vagrantfile en tu directorio y ahorrarte el "vagrant init" si quieres.

Una vez tenemos esto, escribiremos

$> vagrant up

Esto descargará la box de la web de Vagrant Cloud a nuestro ordenador, la importará al listado de boxes de Vagrant y luego creará una máquina virtual en VirtualBox, donde instalará el Sistema Operativo con toda una serie de configuraciones por defecto. El resultado final es que tendremos una máquina virtual con Ubuntu completamente funcional para que podamos trabajar con ella.

Así de sencillo. Todo el proceso de creación de esa máquina virtual habrán sido dos minutos más lo que tarde tu conexión a internet en descargar la box base (que no suele ser más de 200MB o 300MB).

¿Hay naves más allá de Orión?

Esto solo es el primer paso en el maravilloso mundo de la virtualización. Es un paso muy sencillo en un mundo muy complejo pero que trae muchos beneficios en cuestión de automatización y ahorro de tiempo.

Puedes leerte la documentación de vagrant para profundizar más.

Puedes también explorar Ansible, Chef o Puppet, que son softwares de aprovisinamiento. Este software permite automatizar el despliegue de software, incluyendo configuración. Se suele usar junto con Vagrant (y otros sistemas de virtualización) para hacer instalaciones y configuraciones más complejas.

Un ejemplo de lo que puede hacerse con el software de aprovisionamiento es desplegar una máquina con Vagrant como la del ejemplo y luego que ejecute una instalación de Apache, MySQL y PHP, configure un VirtualHost de Apache, te coja el código de un repositorio de Git de tu web, la despliegue, te instale la base de datos de la web, la configure y básicamente te deje todo tu site montado y funcionando en esa máquina virtual. Y tu solo has tenido que escribir "vagrant up".

Pero de todo esto ya hablaremos otro día.