Continuous deployment con GitHub, Bitbucket, DigitalOcean y dploy.io

Después de estar investigando posibles soluciones para montar un sistema de 'integración continua' sencillo y mantenible compatible con GitHub, Bitbucket y DigitalOcean, monté esta solución apoyada en un servicio de despliegue continuo llamado dploy.io.

Entorno de producción

Antes de nada vamos a repasar el entorno de producción:

  • Servidor Debian 7.0 x32
  • Node.js
  • Grunt.js
  • pm2

La aplicación se encuentra en la ruta /www/continuous-deployment-dploy.io/ corriendo con pm2 y la opción de watching.

El proyecto está hosteado en GitHub.

Objetivo

El objetivo que queremos conseguir con todo esto es el siguiente:

  • Al hacer un push a la rama master de nuestro repositorio se desplieguen los cambios en una ruta segura de nuestro servidor de producción. /checker/continuous-deployment-dploy.io/
  • En esa ruta segura se ejecute toda la batería de test.
  • Si los tests pasan entonces desde la ruta donde está la aplicación en producción se hace un pull al repositorio y se recogen los nuevos cambios.
  • pm2 detecta que hay nuevos cambios en la aplicación y la reinicia.

Configuración de dploy.io

Tenemos todo listo para iniciar la configuración en dploy.io. Así que nos logueamos con nuestra cuenta y vamos al apartado Repositories y le damos al botón Connect a repository.

En la siguiente ventana conectamos con nuestro repositorio de GitHub, Bitbucket o el nuestro propio. En este caso usaremos el de GitHub.

Ahora veremos los repositorios conectados a nuestra cuenta. Antes de seguir adelante configurando el despliegue continuo, vamos a integrar nuestra cuenta de DigitalOcean con la de dploy haciendo clic en Integrations.

Tan sencillo como rellenar nuestro datos de DigitalOcean para conectar la cuenta.

Ahora ya estamos listos para volver a nuestra lista de Repositories y pinchar en el que queremos configurar. En este caso continuous-deployment-dploy.io. Una vez dentro veremos la siguiente pantalla en la que tendremos que configurar nuestros entornos y servidores. Para ello pinchamos en Create Environment & Server.

Puesto que queremos añadir un servidor de nuestra cuenta de DigitalOcean seleccionamos esa opción y hacemos clic en Next Step.

A continuación le damos un nombre al servidor, configuramos que carpetas del repositorio queremos desplegar, el droplet de DigitalOcean y ruta sobre la que queremos desplegar. Fijaros que la ruta de despliegue no es la misma ruta que la de nuestra aplicación en producción (esta es la ruta segura donde se lanzará la batería de tests).

Importante asegurarse que nuestro servidor de DigitalOcean dispone de la clave SSH.

Realizadas las configuraciones obligatorias, vamos con las opcionales. No obstante son muy importantes ya que le vamos a indicar una serie de comandos para ejecutar nuestra batería de tests y si todo va bien que se haga el despliegue en la ruta donde está la aplicación en producción.

Ya tenemos nuestro sistema de "integración continua" configurado. Para probar que todo funciona podemos hacer un primer despliegue manual pulsando el botón Deploy.

Seleccionamos la revisión que queremos desplegar y un mensaje opcional. Seguimos, pulsando en el botón Review Deployment.

Veremos un review del deploy. Si todo está correcto pulsamos en Start Deployment.

A continuación veremos el histórico de nuestros despliegues y como vemos el despliegue ha fallado. Podemos ver lo que ha pasado pulsando el botón Transfer Log.

Se puede observar claramente un fallo en un Unit test de Mocha.

Arreglamos nuestro código para que pase el test, hacemos un nuevo push a nuestra rama de master y esta vez vemos que es despliegue se ha realizado correctamente.

Si revisamos la monitorización de pm2 vemos que ha reiniciado la aplicación.