El momento más temido por cualquier desarrollador con un par de proyectos web bajo el brazo es el famoso deploy (Despligue, subida a producción o como prefieras llamarle).

En mis comienzos en este mundillo la cosa era simple (o al menos, así lo entendía yo): había un servidor donde la aplicación corría, yo editaba mis archivos y los subía por FTP... ¿qué podría salir mal? Desde acá te escucho reírte :)

Un poco más tarde aprendí que era una mejor idea trabajar en mi computadora (primero instalando todos los componentes por separado, luego usando XAMPP, hacer algunas pruebas y, cuando estaba un poco más seguro de que las cosas funcionaban bien sí, abrir el FTP y ¡a la carga!

Esto mejoró significativamente mi tasa de éxito (Léase: disminuyó significativamente la cantidad de insultos de clientes enfurecidos), pero aún me encontraba ante algunos problemas algo molestos (particularmente a la hora de usar hostings compartidos): a veces las versiones del software de base que yo usaba no eran exactamente las mismas que estaban a mi disposición en el servidor. Peor aún, muchas veces trabajaba en varios proyectos diferentes a la vez (Cada uno a ser desplegado en un servidor diferente)... instalar en mi propia computadora todas las versiones de todos los programas necesarios se me hacía realmente complicado.

Y así vivía triste hasta que me crucé con las máquinas virtuales.

Trabajar con máquinas virtuales te permite tener un ambiente de desarrollo tan cercano al de producción como quieras (o hasta donde puedas llevarlo...), lo cual hace que la aparición de esas pequeñas (¡pero catastróficas!) incompatibilidades no se produzcan. En definitiva, se trata de tener más control sobre los ambientes donde tu código va a ser ejecutado.

Por otra parte, trabajar con máquinas virtuales hace más simple la experimentación: si probaste un paquete que no te convenció podés descartar la MV y empezar de nuevo, podés compartir tu entorno de trabajo con otros desarrolladores simplemente pasándoles un archivo (grande, es cierto, pero archivo al fin).

Y si a todo esto le sumás la posibilidad de automatizar el montaje de la MV se vuelve una opción difícil de resistir. Herramientas para lograr esto hay varias, no voy a meterme en mucho detalle, sólo comentarte una muy útil (y que vas a necesitar para poner en práctica este post): Vagrant. Vagrant es precisamente eso: una herramienta de automatización de máquinas virtuales. Es como si fuera una tienda de hardware virtual, sólo tenés que hacer tu pedido (Describir la máquina que querés construir) y Vagrant se encarga de hacerlo posible (Con la ayuda de algún motor de virtualización como VirtualBox).

Pues bien, como te podrás imaginar, una vez que el hardware está en su lugar le toca el turno al software.

Particularmente, si estás pensando en un proyecto Symfony, lo más probable es que estés ante un desarrollo web (WebApp, API o similar), con lo cual, ante todo, vas a necesitar un webserver.

Una práctica recomendada desde Symfony es el uso del webserver incorporado en PHP para desarrollar. Mi opinión es que es una solución de muy corto plazo. Si pensás hacer algún desarrollo medianamente complejo, ¿para qué perder tiempo y correr riesgos innecesarios? Más vale instalar el software que soportará tu sistema una vez en producción.

Probablemente también necesites algún motor de bases de datos (¿MySQL tal vez?) y, por supuesto, php (Si no, ¿cómo pensás ejecutar tu código?).

Y por último, si vas a usar algún IDE (Vas a usar un IDE, ¿cierto?), no vendría mal contar con alguna forma de debuggear (Que no sea llenar el código de var_dump), por ejemplo XDebug.

La instalación de todo este arsenal implicaría un tiempo importante (sobre todo si tenés que hacerlo cada vez...), sería mejor contar con una herramienta de automatización de instalación de software (Por ejemplo Ansible o Puppet). Te tendrías que armar tu propio archivo de configuración con todo esto, pero al final te quedaría algo bastante bueno.

O bien podrías usar Laravel/Homestead y ahorrarte una gran cantidad de pasos :)

Laravel/Homestead

Suena un poco raro en un post de Symfony hablar de Laravel, ¿cierto?. En mi opinión, no hay nada de malo en usar paquetes de diferentes frameworks (Siempre que sumen, bienvenidos), pero entiendo que en este pequeño mundillo de la programación (y PHP no se escapa), existe mucho amor por las herramientas... intentaré no ofender a nadie :)

Empecemos por entender de qué se trata Homestead. Técnicamente es un paquete que permite crear de forma muy simple una máquina virtual con:

La gente que está detrás del proyecto Laravel se encontró con una problemática similar a la que te expliqué y decidió tomar cartas en el asunto: diseñaron un paquete (que es casi una aplicación en sí misma) que resuelve todo esto con unos simples comandos (y un pequeño archivo de configuración YAML).

Para usarlo necesitás:

  1. Instalar Vagrant
  2. Instalar algún motor de virtualización (te recomiendo VirtualBox, pero podés usar otros).
  3. Agregar la dependencia a tu archivo composer.json (Asumo que estás usando composer): composer require laravel/homestead
  4. Instalar la nueva dependencia composer install
  5. Armar el entorno virtual php vendor/laravel/bin/make

El último comando hace uso de toda la magia subyacente (Vagrant, VirtualBox y demás) y termina dejando en tus manos un archivo llamado Homestead.yaml y otro llamado Vagrantfile. En el primer archivo se encuentra toda la configuración de tu instancia de Homestead, el segundo es un archivo de configuración de Vagrant (es conveniente no tocarlo ya que, salvo casos especiales, vas a preferir que Homestead lo administre).

El archivo Homestead.yaml

La primera configuración que deberías notar es:

folders: - map: /home/yo/miapp to: /home/vagrant/Code/miapp

Esta entrada le dice a Homestead que configure (en realidad, le dice que le pida a Vagrant que lo haga por él, pero bueno... pequeño tecnicismo) un mapeo entre el directorio "real" (/home/yo/miapp) y el virtual (/home/vagrant/Code/miapp). Tener este mapeo es sumamente útil: permite que todos los cambios que hagas en /home/yo/miapp automáticamente se reflejen en la máquina virtual. Es como si estuvieses editando directamente los archivos de la máquina virtual (O, si estuvieses desplegando tu código a través de FTP, como si estuvieses editando directamente sobre el servidor de pruebas... imaginate el tiempo que vas a ahorrar en transferencias y en detectar si el archivo que modificaste está subido o no...). Se pueden hacer más toques a la configuración, pero con esto va a ser suficiente en la gran mayoría de los casos.

La siguiente configuración que tenés que conocer es la de sites. El caso de uso "normal" de Homestead es tener una única MV para todos tus proyectos. Yo prefiero tener cada proyecto con su propia máquina ya que, por lo general, cuando pongo algo en producción lo hago en un nuevo servidor (Habiendo VPSs por U$5 al mes no lo dudo demasiado :), pero si ese no es tu caso (Si tenés varios proyectos viviendo en el mismo servidor) tal vez te convenga usar una única instancia de Homestead, la idea acá es siempre contar con un entorno de desarrollo tan similar al de producción como sea posible.

Es por eso que Homestead utiliza el concepto de sites. Conceptualmente es muy similar al de VirtualHosts, en la práctica todo se traduce en un algo como:

sites: - map: miapp.app to: /home/vagrant/Code/miapp/web

Con esta configuración estás indicando a Homestead cómo debe configurar tu webserver (NginX en este caso) para tomar el directorio /home/vagrant/Code/miapp/web como raíz del host virtual miapp.app.

Si bien no es estrictamente necesario, es muy cómo poder acceder a tu aplicación escribiendo algo como http://miapp.app. Para lograr esto necesitás que tu computadora sea capaz de entender que miapp.app mapea a la IP de la MV (Por defecto 192.168.10.10, en todo caso, consultá tu archivo Homestead.yaml).

Para lograr este efecto sólo tenés que modificar tu archivo hosts (En Ubuntu lo encontrás en /etc/hosts, en Windows en C:\Windows\System32\drivers\etc\hosts) y agregar una entrada:

192.168.10.10 miapp.app

Una pequeña, pero super importante, aclaración: La estructura de directorios que usa Laravel es algo diferente de la usada por Symfony. Esto hace que algunas configuraciones del webserver y los directorios compartidos (Entre tu computadora física y la virtual) sean diferentes, con lo cual, si lo intentás directamente vas a tener problemas (Nada muy grave, pero vas a pasar un rato peleando y Googleando).

Una forma muy simple de evitarte todos esos dolores de cabeza es configurar el tipo de proyecto como symfony (Sí, sí, estos muchachos pensaron en todo :):

sites: - map: miapp.app to: /home/vagrant/Code/miapp/web type: symfony

Existen varios tipos diferentes de sitios que pueden usarse con Homestead, pero como este artículo se trata sobre Homestead para Symfony, te los dejo de tarea para el hogar :)

Una vez que la configuración esté completa hay que aplicarla. Este trabajo se lo dejamos directamente a Vagrant: vagrant reload --provision si la máquina ya estaba encendida o vagrant up para encenderla por primera vez.

Con este comando vagrant hará su magia y terminarás con:

  1. El webserver listo para correr tu aplicación
  2. La máquina virtual configurada para tomar tus cambios instantáneamente

En lo que respecta a administración del uso normal de la máquina virtual lo que aporta Homestead es poco, probablemente te convenga usar directamente los comandos de vagrant:

  1. vagrant ssh para ingresar a la MV
  2. vagrant halt para apagarla por completo
  3. vagrant up para iniciarla después de un halt
  4. vagrant suspend para dejarla hibernando
  5. vagrant resume para levantarla de la hibernación

Pero en lo que a configuración/instalación inicial se refiere, Homestead es un salto cualitativo importante.

Por último, al ser un paquete estándar y, sobre todo, estar manejado por composer, vas a gozar de las actualizaciones en la configuración sin hacer un gran esfuerzo adicional (Por ejemplo, recientemente se cambió el intérprete de PHP que se utiliza siguiendo la tendencia de ir a la version 7).

¡Listo! Se acabaron las excusas para no usar máquinas virtuales en tus proyectos Symfony.