Introducción a Vagrant, la mejor forma de preparar un proyecto web. Parte I

vagrant01

Y es que después de su par de años de maduración, Vagrant ya es una de las herramientas más utilizadas por todos los desarrolladores web, administradores de sistemas y cualquier profesional IT que quiera testear un entorno de servidores, ya sea Linux o Windows (aunque principalmente Linux).

Para que el que no lo conozca, Vagrant es una herramienta que permite generar una máquina virtual (para Virtualbox, VirtualPC o VMWare) preconfigurada y con acceso remoto, en unos pocos minutos, y fácilmente distribuible.

¿Para qué sirve?. Bien, pensemos que estamos desarrollando una página web en PHP, y necesitaremos por tanto en nuestro ordenador poder disponer de un servidor web con PHP y seguramente MySQL. Esto en el mejor de los casos, porque realmente nos podríamos encontrar con entornos con Dyango, RubyOnRails, NodeJS y alguno de sus innumerables frameworks web. Instalar todo esto en nuestro ordenador de trabajo además de ser tedioso, termina siendo insufrible debido a las diferencias en entornos Windows, Linux y OSX, cuando al final tendrá que estar funcionando sobre un servidor Unix de un hosting.

Hasta hace muy poco, la mayoría acudíamos a algún entorno LAMP (si hablamos de Apache+PHP+MySQL), un WAMP (en Windows) o quizás un MAMP (en OSX). Esto era bastante fácil, pero si tu proyecto empezaba a requerir más requisitos en cuestión de nuevos módulos de PHP, acceso a indexadores como ElasticSearch, Sphinx, etc… la instalación y compilación de estos módlos y dependencias se iba complicando.

A esto sumamos a este bonito cuadro, que nuestros compañeros con los que trabajamos en el mismo proyecto, uno tiene un Mac, otro un Windows y otro quizás un Linux. Resultaba imposible ayudar a nuestro compañero dándole instrucciones de cómo han montado el entorno, puesto que cada uno lo ha hecho en su propio sistema operativo.

Vagrant nos elimina todos estos problemas además de poder generar un entorno homogéneo para todo el equipo y que puede ser un clon de lo que tendremos en nuestro servidor más adelante a la hora de publicar nuestro proyecto en producción. Podremos pasar la configuración de nuestra máquina Vagrant, y un proceso de setup que instalará todo el entorno que necesitemos.

Lo primero que necesitamos saber es que podemos usar Vagrant de muchas maneras. La primera es instalar un sistema base, por ejemplo Ubuntu 14.04 escribiendo:

mkdir ubuntu
cd ubuntu
vagrant init precise32

Esto nos creará un fichero Vagrantfile, que podemos editar con un editor de texto.Desde este fichero podemos modificar la memoria RAM asignada, asignar carpetar compartidas, etc…

Una vez configurado podemos ejecutar:

vagrant up

Todos los comandos de vagrant deberemos ejecutarlos sobre la carpeta donde tenemos el Vagrantfile, de otra manera Vagrant no sabrá con que maquina virtual está trabajando. Esto descarga Ubuntu, y genera una máquina virtual ya preinstalada con este SO. Podremos entrar en la máquina virtual a través de SSH por línea de comandos, aunque si nunca hemos manejado un linux, es posible que se nos atragante.

vagrant ssh

Aquí tenemos una ligera diferencia, si usamos Windows, no tenemos de serie un cliente SSH, por lo que necesitaremos o bien instalar CygWin, GIT for Windows, o mejor aún Babun (una versión retocada de CygWin mejorada para Windows de la que hablaré próximamente).

Una vez instalado en Windows, con Babun podremos trabajar normalmente.

Lo interesante aquí es que podamos generar una máquina virtual que nos permita que no trabajemos continuamente con la línea de comandos, y que podamos configurar el servidor fácilmente desde una interfaz web.

Podemos sobre este sistema base configurarlo y posteriormente exportarlo como un fichero .box que podemos pasar al resto del equipo, una vez tenemos exportada la máquina virtual, podemos compartirla con la comunidad desde la web de Hashcorp, la empresa que está detrás de Vagrant, de forma gratuita.

He compartido una máquina Vagrant que tiene lo necesario para trabajar con Apache, Nginx, PHP 5.5, MySQL (MariaDB 5.5), NodeJS, Composer, Bower.

Podéis descargarla en: https://github.com/sevir/vagrant-webserver una vez descargado, entrar en la carpeta para ejecutar un vagrant up.

Esta máquina virtual además de llevar preinstalado gran parte del sistema, actualiza e instala ciertos componentes en el momento de generar una nueva máquina virtual. A esto le llamamos provisioning, con Vagrant podemos provisionar un servidor de varias maneras, la más sencilla es ejecutar scripts de shell con los comandos que nosotros queramos, otra forma es utilizar algún software de provision de servidores como Puppet, Chef o Ansible de los que hablaremos próximamente.

Actualización: Esta mañana en el trabajo me han hablado de la existencia de una extensión para Vagrant que podemos instalar para mantener siempre actualizada la versión de las VBGuest Additions que instalan mayor soporte para VirtualBox en la máquina virtual (en resumen hace que vaya más rápida). Simplemente ejecuta antes del vagrant up:

vagrant plugin install vagrant-vbguest
ci_ajax_jsonp

Servicios web JSONP y AJAX – iframe fácil en CodeIgniter

ci_ajax_jsonp

Aunque hace bastante tiempo de esto, aún tiene mucha utilidad. Se ha convertido en una costumbre que las aplicaciones webs estén pobladas de consultas o peticiones AJAX, cargando inicialmente una plantilla, y actualizando los contenidos mediante consultas o peticiones asíncronas.

Cuando queremos subir ficheros en segundo plano sin realizar la carga, en cambio no podemos usar AJAX, teniendo que remitirnos al File API de HTML5 o bien buscar una técnica alternativa que permita enviar un formulario con un formulario en multipart en segundo plano. Esto se puede conseguir mediante iframes, la técnica se basa en crear un iframe no visible (que no oculto, si está display:hidden no funcionará), de un tamaño de 0 pixeles y sin bordes conseguiremos un iframe funcional pero que no es visible por el usuario. Si indicamos como target de un formulario multipart este iframe, podremos subir un fichero sin recargar la página.

El problema será entonces conocer el momento en que el archivo se ha terminado de subir, para esto la respuesta cargada en el iframe debe ejecutar una llamada JavaScript definida en la ventana padre, que como si fuese una función de Callback se ejecutará cuando tengamos subido el fichero.

Poder obtener datos en JavaScript entre diferentes dominios permitirá crear fácilmente servicios web en formato JSON, a esta técnica se le denomina JSONP, consiste en devolver no un objeto JavaScript sino la llamada a una función con el nombre que escojamos (función callback) pasando como parámetro este objeto.
Cuando cargamos una url con la llamada al servicio lanzaremos la ejecución de la función de callback con los datos que esperamos de respuesta. Esto ya lo hace jQuery por detrás cuando ejecutamos el método $.getScript generando una función con un nombre aleatorio.

Para todo esto tenemos una librería que nos ayudará para generar respuestas en formato JSON, JSONP, XML y respuestas a través de iframes, si usamos CodeIgniter 2 o superior, mediante Spark/ajax disponemos de una serie de funciones helpers y métodos útiles para generar respuestas válidas en JSONP, envío de respuestas dentro de un iframe o respuestas en XML.

Con un método $this->ajax->response() podremos generar respuestas para enviar como JSON, JSONP, extender un objeto JS con jQuery, asignar datos generados a una variable, o generar respuestas en XML a partir de un objeto PHP.

Por ejemplo queremos cargar las cadenas de traducción de un array PHP a una variable JavaScript, podríamos añadir una carga de script en HTML

< script type="text/javascript" src="http://url/controller/method">

y que este método PHP devuelva los datos en una variable:

$this->ajax->response($array_traduccion, null, TRUE, "varjs");

Esto cargará los datos en varjs para poder usarlo en JavaScript. Esto funcionaría también en cualquier dominio, por lo que sería cross-domain.