Alojando una web en IPFS

En el primer post vimos como interactuar con IPFS de forma sencilla. Ahora vamos a dar un paso más y vamos a alojar una web en IPFS, aprovechando todas las ventajas de escalabilidad y disponibilidad que nos ofrece la red. Para ello usaremos además otro protocolo llamado IPNS, que sería similar a DNS pero en la red IPFS.

Las páginas ideales para IPFS actualmente son las que siguen el JAMstack, es decir, uso extensivo de JavaScript en el cliente, que podrá conectarse a APIs para obtener/actualizar información. Las APIs no tienen por qué ser centralizadas, ya que JavaScript con WebRTC puede buscar peers, posibilitando APIs descentralizadas.

Generando el contenido estático

El primer paso será generar el contenido estático de la web. Para ello existen herramientas muy conocidas como Jekyll, Hugo o Pelican.

No nos vamos a alargar más en esto, ya que cada herramienta tiene sus pasos. El resultado final será una carpeta con ficheros HTML, CSS, fuentes, imágenes y JavaScript.

Subir a IPFS

Teniendo el nodo IPFS en funcionamiento, subimos la carpeta del modo habitual, en mi caso, voy a subir la página que está en http://adrianistan.eu .

Y anotamos el último hash.

Comprobamos que la web es accesible, tanto desde la gateway del nodo, como una externa:

Tanto en el nodo local como en uno externo, la web carga perfectamente con el hash

IPFS tiene direccionamiento por contenido

En el post anterior mencionamos que IPFS direcciona por contenido gracias a los hashes. Esto tiene unas consecuencias interesantes. Por ejemplo, si se añade un archivo duplicado a IPFS, este tiene exactamente la misma dirección, ya que comparten hash. Por otro lado, los documentos no se pueden actualizar, porque entonces su hash cambia. Sin embargo en una web queremos cambiar contenido, ahí entra en acción IPNS.

IPNS, gestión de nombres para IPFS

IPNS es un protocolo parecido en intenciones a DNS que redirige un ID única al hash correspondiente en ese momento. Registramos el hash de la web actual en IPNS.

Ahora sí, el hash IPNS puede publicarse por la red, ya que siempre apuntará a la última versión de la web.

Para acceder a recursos a través de IPNS tenemos que cambiar de protocolo, en vez de /ipfs/HASH, tenemos que poner /ipns/HASH. Vale tanto para comandos como para las gateways HTTP.

https://cloudflare-ipfs.com/ipns/QmYDVeoadAzk9ZW6zwJK3E3KHrA1LWLveEdqUv4XAcCjKa/

En cualquier momento podemos comprobar a que dirección IPFS apunta el hash IPNS:

Para actualizar el contenido simplemente se vuelve a repetir el paso de ipfs name publish. IPFS automáticamente modificará la redirección de IPNS.

Los contenidos antiguos no desaparecen, pero pueden no ser accesibles ya que ningún nodo tenga copia de ellos.

DNSLink

Aún así, ir dándole a la gente un hash IPNS es demasiado complicado. Afortunadamente, podemos usar el DNS tradicional para indicar una ruta IPNS y así, como veremos, facilitar bastante las cosas.

Para ello añadimos un campo TXT en los DNS de nuestro dominio. El contenido es el siguiente:

Con esto podremos usar /ipns/dominio.com en la red IPFS. Pero todavía hace falta un cliente IPFS.

Afortunadamente, podemos redirigir mediante CNAME a una gateway HTTP de confianza y ¡la web funcionará correctamente! Para ello hay que crear un campo TXT en el subdominio _dnslink con el mismo contenido que el anterior.

Todas las gateways de IPFS soportan DNSLink para que la transición a IPFS sea lo más transparente posible.

Así, finalmente la página carga con un dominio normal y corriente en un navegador normal y corriente.

Fijaos en la URL

De hecho, vosotros mismos podéis acceder:

http://adrianistan.yayeyo.ga

IPFS Companion

Si usamos mucho IPFS, puede que nos interese una extensión que maneje el protocolo ipfs:// . Tanto en Firefox como en Chrome existe IPFS Companion, una extensión que nos permite acceder a contenido IPFS de forma sencilla.

Servicio systemd

Por último, quiero dejar el servicio de systemd necesario para tener el nodo IPFS funcionando constantemente en nuestro ordenador. En este caso, IPFS lo instalé vía Snap.




Y con esto ya tendríamos suficiente como para jugar con IPFS un buen rato.

Tutorial de Hugo en español, generador de sitios estáticos

Los generadores de sitios estáticos son aplicaciones que dados unos ficheros generan un sitio web completo, listo para ser desplegado en Apache o Nginx. El generador es llamado bajo demanda del administrador por lo que, al contrario que en un CMS completo, este programa solo genera las páginas una sola vez, reduciendo considerablemente la carga de trabajo y el precio y aumentando en velocidad y rendimiento.

hugo

Los generadores más populares son:

Nombre Lenguaje Plantillas Licencia Sitio web
Jekyll Ruby Liquid MIT http://jekyllrb.com
Hexo JavaScript EJS y Swig MIT http://hexo.io
Hugo Go Go Template, Acer y Amber Apache http://gohugo.io
Pelican Python Jinja2 GPL http://blog.getpelican.com

Además es también bastante conocido Octopress pero Octopress no es más que Jekyll con una colección de utilidades extra, el núcleo del programa sigue siendo Jekyll.

¿Por qué voy a elegir Hugo? Yo empecé con Jekyll y me gustó. Sin embargo Liquid no me acabó de convencer nunca y miré otras alternativas. Hexo me pareció excelente si lo que quieres hacer es un blog, funciona muy bien y es más rápido que Jekyll pero Jekyll tenía la ventaja de que se podía usar no solo en blogs, sino en cualquier web en general. Entonces oí hablar de Hugo. Hugo es el más rápido y el más flexible. No está enfocado solo en blogs, soporta todo lo que le eches. Sin embargo me parece que Hugo no es el más sencillo de configurar, así que aquí va el tutorial.

Instalando Hugo

Hugo está hecho en Go, quiere decir que está compilado y por tanto hay una versión diferente para cada sistema operativo. Descarga la versión de tu sistema operativo desde aquí. Si usas GNU/Linux es posible que tu distro haya empaquetado ya Hugo. Búscalo.

Una vez lo tengamos instalado comprobamos que todo esté en orden:

Por defecto Hugo no trae ningún tema. Si quieres instalarte uno y no crear uno de cero puedes clonarlos desde Git. Si quieres probar los temas antes de instalarlos no dejes de mirar Hugo Themes

Si queremos tener coloreado de sintaxis podemos usar Pygments. Si tienes PIP instalado es fácil.

Además si quieres activar el autocompletado de Bash solo tienes que hacer

Y con esto ya tenemos Hugo instalado correctamente. Ejecuta:

hugo-themes

Organización en Hugo

En Hugo tenemos que tener muy en cuenta la organización de los ficheros. En primer lugar van los themes. Como puedes comprobar la carpeta themes generada esta vacía. Para ir probando los distintos temas puedes hacer un sencillo enlace simbólico entre la carpeta con los temas descargada y esta.

Veamos el resto de carpetas:

  • archetypes. Arquetipos. Son plantillas para cuando añadimos un nuevo elemento. Por ejemplo, podemos tener un arquetipo de post sobre un vídeo de YouTube. Es posible crear un arquetipo que contenga configuración ya específica (categorías, reproductor insertado, etc) y que cuando escribamos ya lo tengamos medio hecho. A la hora de generar el sitio los arquetipos de origen no son tenidos en cuenta.
  • config.toml (o config.json o config.yaml). Este archivo contiene la configuración del sitio.
  • content. Aquí va el contenido central de la web. Dentro de content debes crear tantas carpetas como secciones tengas (aunque se puede sobreescribir vía configuración, es práctica recomendada). Cada sección tiene asignado un layout distinto. Dentro de la carpeta de cada sección la organización es libre, los archivos suelen ser de Markdown, pero HTML puro también vale.
  • layouts. ¿Cómo se organiza el contenido? Los layouts son la respuesta. Por cada sección hay que crear mínimo dos layouts, uno para mostrar un contenido solamente y otro para múltiples contenidos del mismo tipo (listas).
  • data. Aquí puedes almacenar archivos en JSON, YAML o TOML a los que puedes acceder desde Hugo. Estos archivos pueden contener cualquier tipo de información, piensa en ellos como en una especie de base de datos.
  • static. El contenido estático, imágenes, JavaScript, CSS, que no deba ser procesado por Hugo debes ponerlo aquí.

Configuración

Dentro del fichero config.toml hay que editar unos cuantos valores.

 

También es configurable Blackfriday el motor de Markdown de Hugo, aunque las opciones por defecto son más que suficientes.

Creando contenido

Crea un archivo dentro de content. Puede estar dentro de una sección si así lo prefieres. En Hugo al igual que en Jekyll cada contenido tiene un front matter, es decir, los metadatos se añaden al principio en un formato que no se va a renderizar. Hugo soporta TOML, YAML y JSON. Si usamos TOML, los delimitadores del front matter serán +++, si usamos YAML --- y si usamos JSON tenemos que poner un objeto con las llaves, {}

Podemos crear variables nuevas a las que podremos acceder desde .Params. Otras opciones predefinidas son type (que sobreescriben el valor de la sección), aliases (que permite hacer redirecciones), weight (la prioridad cuando el contenido sea ordenado) y slug (permite ajustar la URL del contenido).

Modificando el tema

Puedes modificar el tema usando la carpeta layouts. En el fondo un tema es una colección de layouts y recursos estáticos que son combinados con el tuyo. Si ya usas un tema y solo quieres realizar pequeñas modificaciones puedes editar el tema directamente. Si quieres añadir nuevas secciones o crear un tema de 0 entra a la carpeta layouts.

Hay varias subcarpetas dentro de layouts importantes:

  • _default. Es la que se usa cuando no hay otro disponible. Normalmente los temas sobreescriben esta carpeta. Si sobreescribes esta carpeta perderás el tema.
  • index.html. La página de entrada a la web
  • partials. En este carpeta se pueden guardar trozos HTML reutilizables para ser usados por los layouts.
  • shortcodes. Son pequeños trozos de HTML reutilizables con parámetros de entrada para ser usados por el contenido.

Dentro de cada layout (como en _default) tiene que haber mínimo dos archivos. Un archivo single.html que se usará cuando solo se tenga que representar una unidad de ese contenido y un archivo list.html que se usará cuando sea necesario mostrar un conjunto de esos contenidos.

Estos archivos han de programarse usando el motor de plantillas de Go y la API de Hugo. Un archivo single.html básico que muestra el título y el contenido tal cual sería así.

Dentro de las páginas list.html es práctica habitual definir una vista li.html como un elemento individual. Esos elementos individuales se unen para formar la lista en list.html.

Algunos extras

Los shortcodes son pequeños trozos de HTML que aceptan parámetros. Podemos usarlos en el contenido. Piensa en ellos como Mixins de CSS o funciones de JavaScript. Por ejemplo, para marcar un resaltado de sintaxis:

O un enlace dentro de nuestra web: