Montar un blog con Ghost y Docker. Parte I

Crea un blog o sitio web utilizando el CMS Ghost basado en Node y con toda la potencia de Javascript con Docker
Montar un blog con Ghost y Docker. Parte I

Si estás listo para empezar a montar tu pequeño blog y ir contando lo que te pasa en la vida o las cosas que te gustan tan solo necesitarás una cosa: un blog. A la hora de qué sistema utilizar puedes desde crearlo tú desde cero hasta utilizar el todopoderoso Wordpress. Entre estas opciones está Ghost: un CMS basado en Nodejs y Javascript donde denota un aspecto como constante: la simplicidad.

Al contrario de Wordpress, donde tienes complementos o plugins para ampliar su funcionalidad hasta límites insospechados, Ghost va dirigido a aquellos usuarios que únicamente quieran centrarse en escribir: ni gestor de usuarios, ni complementos, ni funciones avanzadas. Tan solo lo que necesitas para escribir: un editor de textos minimista para olvidarte de todo.

Aunque durante años fui fan de Wordpress para montar desde un sencillo blog personal hasta un sitio web empresarial, he decidido darle una oportunidad a Ghost. Y como el movimiento se demuestra andando, este portal es gestionado usando Ghost.

Antes de empezar, etiqueto este artículo también en la categoría de Docker porque vamos a usar Docker para montar nuestro blog. Al fin y al cabo, como buenos IT que somos, utilizaremos las últimas herramientas disponibles no?. Lo haremos así: desde la forma más rápida de tener un portal Ghost disponible hasta tener un entorno más o menos real. Si solo quieres publicar y no quieres ver nada de código, lo mejor es que lo instales de la forma rápida, con el primer paso te vale. Pero si quieres que tu blog esté vivo más de 5 minutos, te recomiendo seguir leyendo el resto de pasos.

Utilizar la imagen oficial

Es tremendamente fácil. Te lo resumo en una línea de código:

docker run -d --name some-ghost -e url=http://localhost:3001 -p 3001:2368 ghost:alpine

En resumidas cuentas, estamos creando un contenedor de Docker a partir de la imagen oficial de Ghost, estableciendo una variable de entorno llamada url con el valor localhost (cámbiala si lo vas a subir a producción por tu dominio) y una redirección desde el puerto 2368 interno del contenedor al puerto 3001 de tu máquina física.

Una vez se haya descargado la imagen de Dockerhub y se haya creado el contenedor, puedes abrir un navegador e ir a "http://localhost:3001". Si todo fue bien, deberías ver Ghost funcionando.

Pues ya está. Ha sido fácil, ¿verdad?. No hemos tardado nada. Sin embargo, unas pequeñas consideraciones que deberías tener en cuenta a la hora de utilizar esto en producción:

  • No hay una base de datos. La imagen de Ghost por defecto no utiliza ningún sistema de base de datos externos; utiliza sqlite (una base de datos contenida en un archivo). Esto quiere decir que no lo puedes instalar en varias máquinas, pues no sincronizarán contenidos.
  • No hay un volumen que contenga la base de datos. Esto quiere decir que el fichero que contiene la base de datos está en el contenedor, no en la máquina física. Por ende, si algún día borras el contenedor perderás todo tu trabajo. Tal vez no sea una buena forma de trabajar si quieres que tu trabajo dure.

Crear un volumen de Docker para alojar la base de datos

Los volúmenes de Docker son algo así como carpetas compartidas entre tu máquina física y el contenedor de Docker. No estaría de más que el fichero de la base de datos estuviese en tu máquina física para poder hacer copias de seguridad y hacerlo de forma independiente al propio Docker. Si haces copias y algún día borras el contenedor tendrás algún soporte para recuperar tu trabajo.

El problema es que si creamos un volumen no tendremos acceso a la base de datos, porque estaremos obligando a Docker a montar un directorio sobre la carpeta del contenedor donde se encuentra la base de datos. Esto quiere decir que lo que realmente hubiese dentro de la carpeta no podrá ser accesible, pues el volumen "sobreescribe" el contenido.

Vamos a extraer del contenedor la base de datos que Ghost creó por nosotros en el paso anterior. Una vez que tengamos el fichero con la base de datos, pararemos y eliminaremos el contenedor

# Creamos una carpeta para las pruebas y accedemos a ella
mkdir pruebas
cd pruebas
mkdir database
# Ahora estaríamos en /home/juan/pruebas (por ejemplo)

# Copiar la base de datos a nuestra máquina
docker cp some-ghost:/var/lib/ghost/content/data/ghost.db ./database/ghost.db

# Paramos el contenedor antiguo y lo eliminamos
docker stop some-ghost
docker rm some-ghost

Ahora, dentro de nuestra carpeta de pruebas deberemos tener una carpeta llamada database y dentro, el fichero ghost.db, la base de datos en sqlite que Ghost utiliza. Vamos a utilizar esta carpeta como volumen y lanzaremos el contenedor de Ghost de nuevo pero indicándole que todo el contenido de la carpeta "/var/lib/ghost/content/data" (que es la ruta local del contenedor donde espera encontrar el fichero) sea cargado desde nuestra carpeta de pruebas:

# Paramos el contenedor antiguo y lo eliminamos
docker stop some-ghost
docker rm some-ghost
# Creamos un Ghost con un volumen
docker run -d --name some-ghost -e url=http://localhost:3001 -p 3001:2368  -v /home/juan/pruebas/database:/var/lib/ghost/content/data/ ghost:alpine

Si lanzamos los anteriores comandos y esperamos (menos que la otra vez porque esta vez ya teníamos la imagen de Docker descargada), veremos que si navegamos a "http://localhost:3001" veremos Ghost funcionando. Y lo mejor es que cada vez que hagamos un cambio (escribamos un artículo o creemos un usuario nuevo), se modificará el fichero ghost.db de nuestra máquina real. Ya no hay escusa para hacer copias de seguridad.

Llegados a este punto, tendremos una versión de Ghost corriendo en un contenedor de Docker y con los cambios de base de datos montados en un volumen entre el propio Docker y nuestra máquina. Not bad, pero...

Todas las imágenes que subamos a los artículos no se guardarán en nuestra máquina, así que si por cualquier catástrofe nuestro contenedor se borra, nos quedamos sin imágenes. Vale! Pues otro volumen para montar las imágenes.

Crear un volumen para las imágenes de los posts

Recuerda que al ser un contenedor nuevo, vamos a parar y borrar el contenido del anterior.

# Paramos el contenedor antiguo y lo eliminamos
docker stop some-ghost
docker rm some-ghost

#Creamos una carpeta dentro de nuestras pruebas para las imágenes
mkdir images

# Creamos un Ghost con un volumen
docker run -d --name some-ghost -e url=http://localhost:3001 -p 3001:2368  -v /home/juan/pruebas/database:/var/lib/ghost/content/data/ -v /home/juan/pruebas/images:/var/lib/ghost/content/images/ ghost:alpine

Y voila! Después de ejecutar el último comando y navegar a "http://localhost:3001" veremos que tenemos Ghost funcionando. Fíjate en que si crear un artículo nuevo y subes una imagen en él, las fechas y el contenido de las carpetas "database" e "images" de tu máquina real habrán cambiado. Esto es porque las imágenes y la base de datos se aloja en tu máquina real y no en el contenedor de docker.

De esta forma, si borrases el contenedor de docker por error y quisieras recuperar el contenido, bastará con ejecutar el último comando anterior para tenerlo todo como estaba antes: las imágenes, los artículos y los usuarios.

Llegados a este punto, tenemos un blog operativo, a prueba de catástrofes y completamente funcional. Si quieres probarlo en producción, súbelo a un servidor, cambia localhost:3001 por tudominio.com y el -p por 80 y verás como funciona. Y sin tener que instalar Nodejs en tu máquina real: entre otras cosas, esa es la gracia de Docker. Esa y que en cualquier ordenador que lo ejecutes funcionará sin tener que hacer mucho más.

Aunque todavía nos falta aplicar la capa de seguridad HTTPS, poder editar el tema y añadir alguna cosilla más, no está mal para empezar. Seguiré actualizando esta saga de artículos hasta que tengamos un blog like-a-pro 💪.

Que tengas un feliz coding !