Ghost: revisited
Como ya expliqué en el post anterior el repositorio oficial de Debian y Ubuntu para node.js ha cambiado, así que aprovechando que estábamos sustituyendo el entorno de pruebas para Ghost en KVM por un contenedor sin privilegios vamos a revisitar nuestra instalación inicial del blog. Esta vez vamos a partir de una imagen inicial de Ubuntu 16.04 ya que hemos actualizado con éxito la distribución en el servidor en el que estáis leyendo estas líneas.
Lo primero es instalar el servidor de Node.js, para ello, como ya comenté anteriormente, han cambiado los repositorios del proyecto para Debian y Ubuntu. Pues bien, vamos a seguir las instrucciones del proyecto para instalar la versión correcta. Vamos a pararnos un momento aquí ya que cuando escribí el primer post, ambos proyectos, Ghost y Node.js, eran muy jóvenes y parece que las cosas no estaban muy ordenadas.
Según el equipo de desarrollo de Ghost, se intenta que la plataforma sólo soporte las versiones LTS de Node.js, cosa que me parece muy sensata. En el enlace que os he puesto podréis consultar la información al respecto, siempre actualizada, por supuesto, habrá que tener en cuenta la versión de Ghost sobre la que estamos trabajando. Un consejo, no os durmáis en los laureles, suscribíos a su newsletter y tan pronto como haya un cambio de versión importante, es decir, de la 0.x.y a la 0.z.y actualizaos, os evitaréis unas horas de investigación que no os supondrán ningún beneficio intelectual, lo digo por experiencia.
En este momento la versión soportada es la 4 por lo que los pasos a seguir son los siguientes:
# curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
## Installing the NodeSource Node.js v4.x LTS Argon repo...
## Populating apt-get cache...
+ apt-get update
Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]
[...]
Mediante este comando se añadirán las fuentes a nuestro sistema y lo único que restará es instalar el servidor en sí:
# apt install nodejs
Ahora vamos a instalar la base de datos que guardará celosamente todo lo que escribamos en nuestro blog:
# apt install mysql-server mysql-client
Durante la instalación se nos pedirá el password de administrador que utilizaremos en los siguientes pasos. Revisando mi procedimiento anterior me di cuenta que no es necesario crear las bases de datos de testeo ya que vamos a trabajar con un entorno similar al de producción. Por esta razón sólo crearemos una base de datos:
# mysql -uroot -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.13-0ubuntu0.16.04.2 (Ubuntu)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database ghost;
Query OK, 1 row affected (0.00 sec)
mysql> create user 'ghost'@'localhost' identified by 'YOUR_PASSWORD';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on ghost.* to 'ghost'@'localhost';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye
Ahora instalaremos nuestro querido y ligero Nginx. Éste tampoco tiene pérdida ya que está disponible en los repositorios oficiales de Ubuntu:
# apt install nginx
Creamos los directorios necesarios para el correcto funcionamiento del servidor con nuestra configuración:
# mkdir /var/cache/nginx
# chown www-data:www-data /var/cache/nginx
# chown www-data:www-data /var/www
Según el artículo que usamos en su día como referencia nuestro archivo de configuración, /etc/nginx/nginx.conf, quedaría así:
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=3000m inactive=600m;
proxy_temp_path /var/tmp;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_comp_level 6;
gzip_vary on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;
upstream ghost_upstream {
server 127.0.0.1:2368;
keepalive 64;
}
server {
listen 80;
server_name libreadmin.es;
if ($host = 'libreadmin.es' ) {
rewrite ^/(.*)$ http://www.libreadmin.es/$1 permanent;
}
location ~ ^/(ghost/signup/) {
rewrite ^/(.*)$ http://libreadmin.es/ permanent;
}
location ~ ^/(img/|css/|lib/|vendor/|fonts/|robots.txt|humans.txt) {
root /var/www/core/client/assets;
access_log off;
expires max;
}
location ~ ^/(shared/|built/) {
root /var/www/core;
access_log off;
expires max;
}
location ~ ^/(favicon.ico) {
root /var/www/core/shared;
access_log off;
expires max;
}
location ~ ^/(content/images/) {
root /var/www;
access_log off;
expires max;
}
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_cache one;
proxy_cache_key ghost$request_uri$scheme;
proxy_pass http://ghost_upstream;
}
location /nginx_stat {
stub_status on;
access_log off;
allow 192.168.99.0/24;
deny all;
}
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Respecto al servidor web sólo nos faltaría activar la configuración específica para el blog, pero primero desactivamos la página por defecto:
# rm /etc/nginx/sites-enabled/default
Y nos creamos un archivo nuevo, /etc/nginx/sites-available/ghost, con el siguiente contenido:
server {
listen 0.0.0.0:80;
server_name libreadmin.es;
access_log /var/log/nginx/libreadmin.es.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:2368;
proxy_redirect off;
}
}
Para activarlo simplemente lo enlazamos en el directorio indicado y reiniciamos Nginx:
# ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost
# systemctl restart nginx.service
Si intentáis ver en el navegador el resultado hasta ahora, os aparecerá un bonito Bad Gateway ya que no hay ninguna aplicación respondiendo en el puerto que le hemos indicado, pero ya podremos instalar Ghost sobre esta infraestructura. Primero descargamos la última versión:
$ curl -L https://ghost.org/zip/ghost-latest.zip -o ghost.zip
Y lo descomprimimos en el directorio adecuado:
# unzip -uo ghost.zip -d /var/www
Para instalar la aplicación en ése directorio ejecutamos lo siguiente:
# npm install --production
# npm install mysql
# npm install forever -g
Este último comando es para lanzar y parar una aplicación de Node.js, en nuestro caso el propio Ghost. Para poder iniciar sin problemas nuestro blog, lo mejor es crearnos un script que ejecute los comandos adecuados, lo llamaremos starter.sh y lo situaremos en el directorio /var/www. Su contenido es el siguiente:
#!/bin/sh
if [ $(ps aux | grep node | grep -v grep | wc -l | tr -s "\n") -eq 0 ]
then
export PATH=/usr/local/bin:$PATH
export NODE_ENV=production
NODE_ENV=production forever start --sourceDir /var/www index.js >> /var/log/nodelog.txt 2>&1
fi
Antes de lanzar nuestro blog debemos establecer los permisos adecuados en el directorio de la aplicación:
# chmod +x /var/www/starter.sh
# chown -R www-data:www-data /var/www/
Y ahora sí podemos activar Ghost:
# ./starter.sh
# forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] n5Za /usr/bin/nodejs index.js 2180 2186 /root/.forever/n5Za.log 0:0:0:3.561
Como véis el blog parece que se ha iniciado correctamente. Para comprobarlo ponemos en nuestro navegador la ip de la máquina en la que hemos realizado todos los pasos y deberíamos ver lo siguiente:
Para futuros testeos, es decir, cuando tengáis los backups de vuestro blog de producción establecidos y restauréis los datos en la máquina de testeo, yo suelo engañar a mi navegador poniendo en mi /etc/hosts la DNS del blog apuntando a la ip interna, así puedo navegar por todos los menús sin miedo a salirme en algún enlace al blog de producción.
Otra forma de restaurar el blog por completo, si no actualizáis durante mucho tiempo, o queréis saltar directamente a una versión limpia de Ghost, pero con el contenido de los posts que habéis creado hasta ahora, pasa por utilizar la exportación de datos en formato json. Esta posibilidad la tenéis en el apartado de Settings, bajo el epígrafe Labs: Export, Export the blog settings and data. Obtendréis un archivo con la configuración del blog, los usuarios y los posts, de esta forma cuando instaléis la nueva versión desde cero, como hemos explicado hoy, no tendréis más que importar este fichero, y como mucho, si utilizáis un tema diferente a Casper, copiarlo directamente en su directorio correspondiente para que vuestro blog aparezca completo. El único post que os sobrará será el que aparece por defecto en la instalación de Ghost, pero borrándolo ya tendréis el blog listo para seguir dando guerra en su nueva ubicación.
Ah, y como dije en el post original de instalación, no olvidéis consultar la guía de uso de Ghost.
Llevamos una época con los zombies muy de moda, no? Pues bien, hace unos años un artista multidisciplinar nos hacía botar salvajemente con su álbum Hellbilly Deluxe, se llamaba Rob Zombie y de este disco os aconsejo su brutal Living Dead Girl una descarga de adrenalina, no muy aconsejable en estas noches tan calurosas, pero por otro lado necesaria para afrontar la vuelta al trabajo.
Enjoy!