Testeando, compilando y desplegando tus aplicaciones NuxtJS gratis con Github Actions y Heroku

Este artículo también está disponible en: English (Inglés)

Así que has desarrollado un pedazo de sitio, blog o portfolio usando NuxtJS… En este artículo trataremos como puedes publicarlo gratis utilizando Heroku

Recuerda que aunque el alojamiento de la aplicación es gratuito, seguirás necesitando tener un dominio registrado si quieres tener algo como miaplicacion.com. De todos modos Heroku te proporciona un dominio del estiloaplicacion-ejemplo.herokuapp.com de forma gratuita.

Aunque en este artículo trataremos como desplegar concretamente una aplicación NuxtJS, estos pasos son muy similares para cualquier aplicación Javascript moderna. Eso si, es posible que no funcione directamente y tengas que hacer algunos ajustes.

Primero pasos

Nuesta aplicación NuxtJS

Vamos a asumir que ya tienes tu aplicación funcionando en tu máquina local, por ello para este ejemplo crearemos una aplicación nueva utilizando el comando create-nuxt-app en npx.

$ yarn create nuxt-app example-app-for-deploy-in-heroku

Así mismo, utilizaremos Jest como suite de testing, aunque puedes utilizar aquella con la que te sientas más cómodo.

Cuenta/Repositorio en GitHub

Será necesario que tengas tu código subido a GitHub, no importa si está marcado como público o privado.

En GitHub, es suficiente con tener una cuenta gratuita. Con este tipo de cuenta dispondremos de 2.000 minutos mensuales para lanzar nuestras acciones (testing).

Creando la cuenta de Github y la aplicación

Al igual que en GitHub, será suficiente contar con una cuenta gratuita, aunque es necesario mencionar que tendrá algunas limitaciones como:

  • Nuestra aplicación arrancará con la primera petición recibida, y quedará en pausa tras 30 minutos de inactividad.
  • Si necesitas utilizar un dominio propio, no podrás disponer de SSL.
  • Como máximo, tu aplicación podrá estar en marcha durante 1.000 horas al mes.

Si crees que algunas de estas restricciones pueden ser un problema, puedes utilizar el plan Hobby que tiene un coste de 7$. Con este tipo tu aplicación siempre estará disponible, además de contar con un dominio propio y certificado SSL.

De todos modos, en este artículo utilizaremos la versión gratuita, por lo que da de alta la cuenta y crea la primera aplicación.

Para que nuestra aplicación funcione, tendremos que configurar una variable de entorno, por lo que haz click en Settingscode>, después en Reveal Config Varscode> y configura la variable HOSTcode> a 0.0.0.0code>. Esta configuración indica a tu aplciación que puede estar disponible en cualquier dirección IP, ya que será Heroku el encargado de proporcionar una IP privada y enrutarla a nuestro host.

Preparando tu código para Heroku

Para este tipo de aplicaciones, Heroku se basa en el fichero package.jsoncode> para elegir el entorno más adecuado, pero será necesario hacer algunos cambios:

La variable de entorno PORT

En Heroku no podemos especificar directamente el puerto interno a utilizar, pero aun así Heroku se encargará de redirigir el tráfico de los puertos 80 y 443 a este puerto interno. Por esto, asegúrate de que en ningún momento estás sobreescribiendo la variable de entorno PORTcode>, y que la usas como puerto de escucha. Puedes asegurarte utilizando este comando:

$ PORT=3333 yarn dev

Si ves algo como esto, funcionará perfectamente en producción:

ℹ Listening on: <http://localhost:3333/>

Versión de NodeJS

También en el fichero package.jsoncode> definiremos la versión del motor de NodeJS que debe utilizar Heroku para nuestra aplicación:

{
  ...
  "engines": {
    "node": "12.x"
  },
  "dependencies": {
    ...
  },
  ...
}

Aprovechando, también podremos especificar qué versión necesitamos para yarncode> o npmcode>.

Compilando la aplicación NuxtJS

Heroku cogerá nuestro código directamente desde GitHub, por lo que será necesario compilarlo antes de lanzar yarn startcode>.

Para esto, Heroku dispone de una serie de hooks que podemos indicar dentro del fichero package.jsoncode>. Por defecto, Heroku utilizará el comando buildcode>, pero si por alguna razón el proceso de compilación es distinto en entorno de producción, puedes especificar la acción a realizar indicándolo en el comando heroku-postbuildcode>.

La rama de producción

Hay que evitar desplegar tu código desde la rama principal del repositorio, por lo que crearemos una nueva rama a la que llamaremos productioncode>. El despliegue se iniciará únicamente cuando esta rama reciba un commit.

Conectando GitHub y Heroku

Volvemos de nuevo a la página de Heroku, y elegiremos GitHub como medio de despliegue.

Una vez conectados, elegiremos la rama productioncode>, y activaremos los despliegues automáticos.

Ahora haremos click en el botón Deploy Branchcode> para iniciar nuestro primer despliegue.

Puedes ver todo el log que se genera en la pestaña Overviewcode> de la sección Latest activitycode>. Una vez que veas el mensaje Build succeededcode>, tu aplicación está en marcha, haz click sobre el botón Open appcode> y… ¡tachan!

Ejecutando tus tests antes de lanzar a producción

Me imagino que no quieres subir una versión de tu aplicación que no pase la batería de test 🙄… Por suerte esto es muy fácil de evitar utilizando GitHub Actions

El primer paso es volver a la sección Deploycode> y asegurarnos de que la opción Wait for CI to pass before deploycode> está activada. Este cambio lo que provoca es que Heroku esperará a que GitHub marque como válido el commit tras ejecutar las acciones asociadas.

Ahora configuraremos una nueva acción para que GitHub lance nuestra batería de test, por lo que crearemos un nuevo fichero en el directorio .github/workflowscode>. Lo llamaremos ci.ymlcode>.

No profundizaremos en el funcionamiento GitHub Actions ya que podríamos hacer cientos de posts sobre la herramienta, pero sí que contaremos qué hace cada uno de los bloques de código:

name: ci
on:
  push:
    branches:
      - production

Este bloque se encarga de configurar el nombre de la acción y le indica a GitHub que debe lanzar esta acción con cada push a productioncode>. Aparte también puedes utilizar pull_request como método de desncadenante.

jobs:
  ci:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        node: [12] 

Aquí configuramos el entorno que queremos utilizar para los tests, para el caso indicamos que queremos utilizar Ubuntu Linux, y la versión 12 de NodeJS, como en el fichero package.json.

steps:
      - name: Checkout
        uses: actions/checkout@master

Este paso recoge el código fuente del commit (La denominación master se refiere a la versión de la acción, no a nuestra rama principal).

steps:
...

      - name: Setup node env
        uses: actions/setup-node@v2.1.2
        with:
          node-version: ${{ matrix.node }}

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - name: Cache node_modules
        uses: actions/cache@v2
        id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

Estos tres pasos preparan el entorno de NodeJS, y configura la cache de Yarn. El hecho de configurar una caché nos permite acelerar el despliegue, ya que no será necesario volver a descargar de nuevo las dependencias.

steps:
...

      - name: Install dependencies
        run: yarn

      - name: Run tests
        run: yarn test

Como último paso, instalaremos las dependencias y lanzaremos nuestra batería de test.

Si alguno de los procesos fallan, la acción se detendrá y no se provocará ningún despliegue en Heroku. Sube este fichero a tu repositorio, y haz tu primer merge a la rama productioncode>. En este caso, podremos ver el resultado en la pestaña Actionscode>:

Si todo ha ido bien, Heroku empezará a compilar nuestra aplicación. Si algo ha ido mal, recibiremos una notificación desde GitHub y no se habrá provocado despliegue.

Aquí tienes el repositorio NuxtJS de la aplicación demo.

Esperamos que este artículo te ayude a mostrar al mundo tu nueva aplicación 🥰.