Cómo desplegar tu sitio en Gatsby a Firebase Hosting

13 febrero, 2020

6 minutos de lectura

💻 Desarrollo

¿Ves alguna errata o quieres modificar algo? Haz una Pull Request

Recientemente he migrado este blog a Gatsby para hacerlo más serverless y mi intención era subirlo a un CDN e implementar integración continua para olvidarme de desplegar manualmente. En este artículo te explico cómo lo he montado yo con Firebase Hosting y Travis. ¡Vamos a ello!

Instalar Gatsby e iniciar proyecto

Lo primero es tener un sitio, o blog, con Gatsby. En futuros posts hablaré sobre el y cómo he configurado mi sitio. En éste artículo vamos a centrarnos en el despliegue continuo, por ello voy a tomar de ejemplo el gatsby-starter-blog como punto de partida.

Para ello, primero necesitamos tener instalado node.js en nuestro equipo para poder instalar el CLI de gatsby de forma global con:

$ npm install -g gatsby-cli

Una vez instalado podemos usar el siguiente comando para iniciar un nuevo proyecto en Gatsby empleando el starter. Esto nos ahorrará tener que crear los ficheros y carpetas.

$ gatsby new TU_BLOG https://github.com/gatsbyjs/gatsby-starter-blog

Sustituyendo TU_BLOG por el nombre que tu quieras. Una vez instalado si ejecutamos lo siguiente tendremos el blog corriendo en local en nuestro equipo en http://localhost:8000

$ yarn develop

gatsby stater

Configurar Firebase Hosting

Vamos a utilizar la funcionalidad de Hosting de Firebase, que actúa como un CDN. Es decir, es un servidor de ficheros estáticos (html's, css's, javascript's) ya que Gatsby lo que hace es en tiempo de build, renderizar todo nuestros contenido como ficheros estáticos.

Para ello nos dirigimos a la consola de Firebase y con nuestra cuenta de Google creamos un nuevo proyecto. Ponle un nombre, elige tu región y ya tienes tu hosting listo para deplegar contenido.

Firebase console crear proyecto

Ahora ve a tu terminal de tu equipo instala las Firebase Tools:

$ npm install -g firebase-tools

Dirígete a la carpeta de tu proyecto creado con Gatsby e inicia Firebase en él después de loguearte:

$ firebase login
$ firebase init

El comando init empezará a preguntarte cosas:

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <sp
ace> to select, <a> to toggle all, <i> to invert selection)
❯◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◯ Functions: Configure and deploy Cloud Functions
 ◯ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features

Con la tecla espacio de tu teclado elige únicamente la opción Hosting

Después elige la opcíon de un proyecto ya existente Use an existing project

? Please select an option: (Use arrow keys)
❯ Use an existing project
  Create a new project
  Add Firebase to an existing Google Cloud Platform project
  Don't set up a default project

Y en la lista de proyectos, elige el que acabas de crear en la consola de Firebase.

En la siguiente pregunta, pulsa enter para elegir public que es donde Gatsby deposita los ficheros estáticos creados por el builder.

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? (public)

Y en las siguientes preguntas escribe N para que firebase no te sobrescriba nada:

? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
? File public/index.html already exists. Overwrite? (y/N)

ya tienes iniciado tu proyecto con Firebase:

i  Skipping write of public/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

Esto nos ha creado dos ficheros en nuestro proyecto:

{
  "projects": {
    "default": "TU_PROYECTO_EN_FIREBASE"
  }
}
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

Que básicamente sirven para que Firebase sepa donde desplegar tu código.

Configurar Travis para despligue continuo.

Ahora vamos a configurar el despligue automático cada vez que actualicemos nuestro blog o añadamos una entrada nueva.

Primero de todo, tienes que crear un repositorio en Github y dejarlo público. En mi caso, el código de mi blog lo puedes encontrar aquí .

Una vez lo tengas, ve a la web de Travis CI para proyectos open source se distingue de la PRO, porque acaba en .org en lugar de .com. Esto hace que nuestros builds sean ilimitados y gratuitos.

Allí enlaza con tu cuenta de GitHub y entre tus repositorios, busca el que acabas de crear para tu sitio Gatsby:

En mi caso, mi url es ésta . Tendrás que activar el repositorio para habilitar travis en él.

activar travis en tu repositorio

Seguidamente ve al menú de opciones y elige settings:

opciones de travis

Aquí vamos a configurar las variables de entorno que usemos en nuestro código, de manera que no queden en el repositorio público a la vista. Una de ellas es el token de Firebase.

Variables de entorno en Gatsby

Para conseguir el token de Firebase podemos hacerlo por línea de comandos con la siguiente instrucción.

$ firebase login:ci

Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=....

Waiting for authentication...

✔  Success! Use this token to login on a CI server:

1//9d85ngk5UNXCkdjdur7bdNwF-L9Irud01Ji3UVC-e7oYNXcp_QGh0yx5ClsWZ8b98hypoaz-8475734_djd

Example: firebase deploy --token "$FIREBASE_TOKEN"

El texto que te aparezca del tipo 1//9d85ngk5UNXCkdjdur7bdNwF-L9Irud01Ji3UVC-e7oYNXcp_QGh0yx5ClsWZ8b98hypoaz-8475734_djd es tu Token, y es el que vamos a guardar en la configuración del dashboard de Travis.

configura tokens como variables de entorno en travis

Ahora ya tenemos Travis listo, sólo nos queda decirle qué tiene que hacer :)

Travis.yml

Vamos a crear un fichero llamado .travis.yml que le sirve a Travis que ejecutar y cuando.

Ésta es la configuración que tengo yo:

language: node_js
node_js:
  - "10"
cache: yarn

branches:
  only:
    - master
before_script:
  - "yarn global add firebase-tools"
  - "yarn global add gatsby"
script:
  - "yarn build"
after_success:
  - "firebase deploy --token=${FIREBASE_API_TOKEN}"

Aquí basicamente le estamos diciendo que utilice node.js v10 y que se ejecuten los comandos solo cuando hay un push o un mergeo a la rama master del repositorio.

El script que va a correr en cada build es yarn build que lo que hace es compilar Gatsby y generar todos los ficheros estáticos de tu blog y colocarlos en la carpeta public.

Antes de esto, con before_script le decimos que tiene que ejecutar para que los comandos funciones que son instalar globalmente las firebase-tools y gatsby

Cuando haya terminado todo (puede llevar varios minutos) y se haya resuelto satisfactoriamente se ejecutarán los comandos en after_success y aquí lo que hacemos es correr el comando de despliegue de firebase utilizando el token que acabamos de guardar en Travis con --token=${FIREBASE_API_TOKEN}

Esto sube el contenido de public al hosting de Firebase.

Primer despliegue

Para ejecutar tu primer despliegue, haz algun cambio como crear un post de prueba dentro de la carpeta content/posts. Haz commit de los cambios y súbelo a tu repo con push.

Esto disparará el build y en unos minutos ya estará disponible a través de una de las URLs que firebase te proporciona, del tipo tu-proyecto.web.app o tu-proyecto.firebaseapp.com.

Ya lo tienes! tu primer blog "serverless" desplegado automáticamente en la nube con travis.

Adicionalmente, Firebase te permite añadir un dominio personalizado (con el SSL automático) si tienes uno en propiedad. Simplemente debes añadir los DNS a tu proveedor de dominios y esperar unas horas a que quede propagado el cambio.

Espero que te animes a probarlo y si te gusta, no dudes en compartir este artículo en tus redes sociales.

© 2023 Carlos Azaustre | Made with 💻 in 🇪🇸