Como está montada esta web (II): Nikola y Google App Engine

En el primer post explicamos las tecnologías utilizadas para desarrollar y hospedar esta web. En esta sección profundizaremos un poco más y daremos los pasos necesarios para que nuestro código HTML estático funcione perfectamente en Google App Engine.

Configuración en conf.py

La documentación de Nikola es muy buena y puede consultarse aquí. Trata prácticamente todo lo configurable en la aplicación, por lo que me voy a centrar sólo en los cambios necesarios (no en el título, o en como cambiar de tema) para que lo generado funcione en la nube de Google.

Nota del autor: Este artículo no representa el estado actual de la web puesto que se ha migrado a Hugo a lo largo del 2020. Para saber más sobre el proceso de migración, puede acceder al siguiente post.

Google App Engine no soporta por defecto Pretty URLs por lo que debemos deshabilitalas en Nikola. Pretty URLS

Pretty URLs son las configuraciones que nos permiten que cuando accedemos a una página web, no tengamos que poner siempre .html al final de cada fichero. Se entiende mucho mejor con un ejemplo: si anteriormente para acceder al post anterior, lo hacíamos a través de la URL https://tangelov.me/como-montada-web-i/ ahora lo haremos a través de https://tangelov.me/como-montada-web-i/index.html .

Este cambio habrá roto algunas de las configuraciones que deberemos cambiar. Todas las referencias internas que no apuntasen al .html directamente fallarían y de caja es lo que pasará con algunas de las URLs de la estructura del tema (archivo, categorías, etc). Procedemos a cambiarlas para que apunten a sus HTMLs. Rutas internas

En mi caso, también cambié el archivo para que fuese un sólo fichero y darle más homogeneidad al conjunto. Archivo

Con esto, nuestro código ya funcionará en GAE, pero también necesitamos desplegarlo.

Configuración de Google App Engine (GAE)

Como ya se ha comentado, Google App Engine es una Plataforma como servicio que permite a desarrolladores, publicar sus páginas web, proporcionando autoescalado, certificados SSL (vía Let’s Encrypt), protección ante caídas de servicio… Google ofrece este servicio en dos modalidades diferentes: standard y flexible

Como nosotros utilizamos HTML puro, podemos usar el standard. Éste se diferencia del flexible por una cantidad más limitada de frameworks que se pueden ejecutar. Actualmente podemos usar Python (2.7, 3.X), Java (8, 11), PHP (5.5, 7.2, 7.3 o 7.4), NodeJS (10, 12, 14 o 16), Ruby (2.5, 2.6 y 2.7) y Go (1.11 o 1.12+).

Antes de realizar el despliegue, necesitamos crear la “infraestructura” en Google Cloud que nos permita hacerlo. En este caso caso concreto la he dividido en dos partes:

  • El servicio de Google App Engine en Europa.

  • Un bucket de Google Cloud Storage donde se almacenan los ficheros estáticos no generados por Nikola.

En primer lugar, si no lo hemos realizado antes, debemos configurar la CLI de GCP en nuestro PC (escribí aquí sobre ello) y realizar las siguientes operaciones (la primera vez).

# Generamos el bucket para almacenar todo el contenido estático no generado por Nikola
gsutil mb -p $nombre_proyecto -c $tipo -l $localizacion gs://$nombre_bucket/

# Damos permisos de lectura para todo el mundo (así es público)
gsutil iam -r ch allUsers:objectViewer gs://$nombre_bucket

# Creamos el servicio de App Engine
gcloud app create --region=europe-west

Con esto ya tendríamos la estructura previa, ahora vamos a generar el fichero app.yaml que necesita App Engine para gestionarlo y a agregar una ligera explicación:

runtime: python39
instance_class: B1

handlers:
- url: /
  static_files: index.html
  upload: index.html
  secure: always

- url: /(.*)
  static_files: \1
  upload: (.*)
  secure: always

basic_scaling:
  max_instances: 1

En este fichero, le estamos indicando al GAE como queremos que se comporte con nuestro código:

  • El runtime se corresponde al framework o lenguaje que estará corriendo por debajo. Por defecto, usa python27 y es el que vamos a usar.

  • api_version lo dejamos en 1.

  • threadsafe se utiliza para que nuestra aplicación sea capaz de realizar peticiones concurrentes.

  • Los handlers se corresponden con el contenido de la aplicación. En este caso le estamos diciendo que suba el index.html a la ruta raiz y que suba todo el resto del contenido. secure indica que siempre se utilizará HTTPS.

  • Por último tenemos el autoescalado: GAE soporta diferentes tipos de autoescalado y yo he elegido el tipo básico y limitarlo a una sola instancia para controlar la factura al máximo. Por ello instance_class apunta a una B1.

Colocamos dicho fichero en la carpeta ~/files dentro de nikola para que cuando ejecutemos las build, lo mueva él mismo a la raíz del código generado.

Despliegues

Personalmente intento organizar el contenido del blog de forma física y lógica: por ello los posts y todos los ficheros asociados a los mismos tienen un código numérico. De esta forma, el post de código 0001-NombredelPost tendrá relacionadas todos los ficheros que comiencen por 0001-*.

Para este ejemplo, vamos a suponer que hemos escrito un nuevo post, que hemos subido todos los ficheros al bucket de Google y que hemos modificado las URLs dentro del post para apuntar hacia allí.

Nikola tiene cosas muy chulas y una de ellas es un soporte nativo para despliegues, pudiendo añadir configuraciones extra que nos los hagan. Tan sólo tenemos que añadirlas al archivo conf.py:

Despliegues en Nikola

Cuando ejecutemos nikola deploy gcloud nos moveremos a la carpeta output y desplegaremos el código ahí generado.

Resumiendo:

  • Cargamos el virtualenv del nikola (source $ruta_del_virtualenv/bin/activate)

  • Añadimos un post (nikola new_post -f markdown) y lo editamos (vi $nombre_del_post)

  • Una vez que estamos contentos con el contenido, confirmamos el cambio (git commit -a -S -m "Algo sobre el post") y lo subimos al repositorio remoto (git push)

  • Subimos los imágenes a un bucket de Google Cloud Storage (gsutil rsync -d ~/images/ gs://$nombre_del_bucket/images)

  • nikola build para generar el HTML (a veces hago un nikola serve para probar el contenido en local)

  • Lanzamos el despliegue: nikola deploy gcloud

Documentación

Revisado a 01/05/2023