Cómo desplegar Ghost Blog con Nginx en Debian 12

Ghost es una plataforma de blogs de código abierto que te ayuda a crear un blog de aspecto profesional. Se lanzó en 2013 como alternativa a WordPress. Está escrito en JavaScript y funciona con la biblioteca Node.js.

En este tutorial, exploraremos cómo instalar Ghost CMS utilizando Nginx y MySQL en un servidor con Debian 12. Utilizaremos el certificado SSL Let’s Encrypt para proteger nuestra instalación.

Requisitos previos

  • Un servidor que ejecute Debian 12 con un mínimo de 2 GB de RAM.
  • Un usuario no root con privilegios sudo.
  • Un nombre de dominio completo (FQDN) como example.com que apunte a tu servidor.
  • Asegúrate de que todo está actualizado.
    $ sudo apt update 
    $ sudo apt upgrade
    
  • Pocos paquetes que necesite tu sistema.
    $ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y
    

    Puede que algunos de estos paquetes ya estén instalados en tu sistema.

Paso 1 – Configurar el cortafuegos UFW

El primer paso es configurar el cortafuegos. Debian viene con ufw (Uncomplicated Firewall) por defecto.

Comprueba si el cortafuegos se está ejecutando.

$ sudo ufw status

Deberías obtener la siguiente salida.

Status: inactive

Permite el puerto SSH para que el cortafuegos no rompa la conexión actual al activarlo.

$ sudo ufw allow OpenSSH

Permite también los puertos HTTP y HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Habilita el cortafuegos

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Comprueba de nuevo el estado del cortafuegos.

$ sudo ufw status

Deberías ver un resultado similar.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Paso 2 – Instala Nginx

Debian 12 incluye una versión antigua de Nginx. Para instalar la última versión, tienes que descargar el repositorio oficial de Nginx.

Importa la clave de firma de Nginx.

$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

Añade el repositorio de la versión estable de Nginx.

$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

Actualiza los repositorios del sistema.

$ sudo apt update

Instala Nginx.

$ sudo apt install nginx

Verifica la instalación. Se necesita sudo para ejecutar el comando en Debian.

$ sudo nginx -v
nginx version: nginx/1.24.0

Inicia el servidor Nginx.

$ sudo systemctl start nginx

Paso 3 – Instalar Node.js

Ghost Installer necesita Nodejs para funcionar. El primer paso es importar la clave GPG de Nodesource.

$ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg

A continuación, crea el archivo del repositorio de Nodesource. Instalaremos Node 18x que es la versión actual LTS (Long Term Support) que es la que recomienda Ghost.

$ NODE_MAJOR=18
$ echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

Actualiza la lista de repositorios del sistema.

$ sudo apt update

Instala Node.

$ sudo apt install nodejs -y

Confirma la instalación de Node.

$ node --version
v18.18.2

Paso 4 – Instalar MySQL con Docker

Debian ya no incluye MySQL. En su lugar, incluye MariaDB. Ghost sólo admite MySQL. Puedes modificar Ghost para que funcione con MariaDB, pero no es recomendable. Como los repositorios oficiales de MySQL no se han actualizado para Debian 12 en el momento de escribir este tutorial, lo instalaremos utilizando Docker.

Importa la clave GPG de Docker.

$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg

Crea un archivo de repositorio Docker.

$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Actualiza la lista de repositorios del sistema.

$ sudo apt update

Instala Docker y Docker Compose.

$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Por defecto, Docker requiere privilegios de root. Si quieres evitar utilizar sudo cada vez que ejecutes el comando docker, añade tu nombre de usuario al grupo docker.

$ sudo usermod -aG docker $(whoami)

Tendrás que salir del servidor y volver a entrar como el mismo usuario para activar este cambio o utilizar el siguiente comando.

$ su - ${USER}

Confirma que tu usuario se ha añadido al grupo Docker.

$ groups
navjot wheel docker

Ahora que el Docker está instalado, necesitamos crear un archivo Docker compose para MySQL. Crea un directorio docker para MySQL.

$ mkdir ~/mysql

Crea y abre el archivo docker-compose.yml para editarlo.

$ nano docker-compose.yml

Pega en él el siguiente código.

services:
  database:
    image: container-registry.oracle.com/mysql/community-server:latest
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_USER: ghost
      MYSQL_PASSWORD: ghostpassword
      MYSQL_DATABASE: ghostdb
    ports:
      - "3306:3306"
    volumes:
      - ./mysql:/var/lib/mysql

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Aquí hemos establecido la contraseña de root y las credenciales MySQL para la base de datos Ghost. Éstas se crearán cuando se ejecute el contenedor.

Inicia el contenedor MySQL.

$ docker compose up -d

Comprueba el estado del contenedor Docker.

$ docker ps
CONTAINER ID   IMAGE                                                         COMMAND                  CREATED         STATUS         PORTS                                                        NAMES
ec42fb205f1e   container-registry.oracle.com/mysql/community-server:latest   "/entrypoint.sh mysq…"   4 seconds ago   Up 2 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060-33061/tcp   mysql

Ghost puede conectarse al contenedor MySQL utilizando el puerto 3306 y realizar operaciones en él.

Paso 5 – Instalar Ghost

También podemos instalar Ghost utilizando Docker, lo que puede simplificar las cosas, pero no lo haremos aquí.

La instalación de Ghost constará de tres componentes: la herramienta de línea de comandos Ghost-CLI, que instala y gestiona las actualizaciones del blog de Ghost, y el propio paquete del blog.

Instalar Ghost-CLI

Ejecuta el siguiente comando para instalar la herramienta Ghost-CLI.

$ sudo npm install ghost-cli@latest -g

Prepara el directorio de Ghost

Crea el directorio raíz de Ghost.

$ sudo mkdir -p /var/www/html/ghost

Establece la propiedad del directorio al usuario actual.

$ sudo chown $USER:$USER /var/www/html/ghost

Establece los permisos correctos del directorio.

$ sudo chmod 755 /var/www/html/ghost

Cambia al directorio de Ghost.

$ cd /var/www/html/ghost

Instalar Ghost

La instalación de Ghost es un proceso de un solo comando.

$ ghost install

Durante la instalación, la herramienta CLI te hará varias preguntas para configurar el blog.

  • URLdel blog: Introduce la URL completa de tu blog junto con el protocolo https. (https://example.com)
  • Nombrede host MySQL: Pulsa Intro para utilizar el valor por defecto de localhost ya que nuestra instalación de Ghost y MySQL están en el mismo servidor.
  • Nombre de usuario de MySQL: Introduce ghost como nombre de usuario de MySQL.
  • Contraseña de MySQL: Introduce tu contraseña de root creada anteriormente en el archivo docker.
  • Nombre de la base de datos de Ghost: Introduce el nombre de la base de datos (ghostdb) configurada en el archivo docker.
  • Contraseñasudo: Te pedirá tu contraseña sudo para realizar tareas administrativas.
  • ¿Has configurado Nginx? Normalmente, Ghost-CLI detecta tu instalación de Nginx y la configura automáticamente para tu blog. Pero eso sólo funciona para Nginx instalado mediante el paquete OS. Como nosotros lo instalamos utilizando el repositorio de Nginx, Ghost no puede detectarlo y lo omitirá automáticamente.
  • ¿Instalar SSL?: Como se ha saltado la configuración de Nginx, la herramienta CLI también se saltará la configuración de SSL.
  • ¿Configurarsystemd? Ghost te preguntará si quieres configurar un servicio de sistema para Ghost. Pulsa Y para continuar.
  • ¿Iniciar Ghost? Pulsa Y para iniciar la instalación de Ghost. Sin embargo, no funcionará porque Nginx y SSL aún no están configurados.

Paso 6 – Instalar SSL

Antes de continuar, necesitamos instalar la herramienta Certbot e instalar un certificado SSL para nuestro dominio.

Para instalar Certbot, utilizaremos el instalador de paquetes Snapd. Snapd siempre trae la última versión estable de Certbot. Sin embargo, Debian no viene con Snapd instalado. Instálalo primero.

$ sudo apt install snapd

Asegúrate de que tu versión de snapd está actualizada.

$ sudo snap install core
$ sudo snap refresh core

Instala Certbot.

$ sudo snap install --classic certbot

Utiliza el siguiente comando para asegurarte de que se puede ejecutar el comando Certbot creando un enlace simbólico al directorio /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verifica la instalación.

$ certbot --version
certbot 2.7.1

Genera un certificado SSL.

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d example.com

El comando anterior descargará un certificado en el directorio /etc/letsencrypt/live/example.com de tu servidor.

Genera un certificado de grupo Diffie-Hellman.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Comprueba el servicio programador de renovaciones de Certbot.

$ sudo systemctl list-timers

Encontrarás snap.certbot.renew.service como uno de los servicios programados para ejecutarse.

NEXT                        LEFT          LAST                        PASSED       UNIT                       ACTIVATES
Tue 2023-10-17 00:00:00 UTC 14h left    Mon 2023-10-16 00:00:18 UTC 9h ago       dpkg-db-backup.timer         dpkg-db-backup.service
Mon 2023-10-16 19:12:00 UTC 9h left     Mon 2023-10-16 07:27:11 UTC 2h 17min ago snap.certbot.renew.timer     snap.certbot.renew.service
Mon 2023-10-16 20:49:14 UTC 11h left    Mon 2023-10-16 07:48:12 UTC 1h 56min ago apt-daily.timer              apt-daily.service

Realiza una ejecución en seco del proceso para comprobar si la renovación SSL funciona correctamente.

$ sudo certbot renew --dry-run

Si no ves ningún error, ya está todo listo. Tu certificado se renovará automáticamente.

Paso 7 – Configurar Nginx

Crea y abre el archivo /etc/nginx/conf.d/ghost.conf para editarlo.

$ sudo nano /etc/nginx/conf.d/ghost.conf

Pega el siguiente código en el archivo ghost.conf. Sustituye todas las instancias de example.com por tu dominio.

server {
  listen 80;
  listen [::]:80;
  server_name example.com;
  location / { 
  	return 301 https://$server_name$request_uri; 
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name example.com;
    
  access_log /var/log/nginx/ghost.access.log;
  error_log /var/log/nginx/ghost.error.log;
  client_max_body_size 20m;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
  ssl_prefer_server_ciphers off;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:10m;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s;
  resolver_timeout 2s;

  ssl_certificate         /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key     /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:2368;
  }
}

La configuración anterior redirigirá todas las peticiones HTTP a HTTPS y servirá como proxy para que el servicio Ghost lo sirva a través de tu dominio.

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.

Abre el archivo /etc/nginx/nginx.conf para editarlo.

$ sudo nano /etc/nginx/nginx.conf

Añade la siguiente línea antes de la línea include /etc/nginx/conf.d/*.conf;.

server_names_hash_bucket_size  64;

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.

Comprueba la configuración de Nginx.

$ sudo nginx -t

Si no ves ningún error, significa que puedes continuar. Reinicia el servidor Nginx para aplicar la configuración.

$ sudo systemctl restart nginx

Paso 9 – Ejecuta el sitio

Ahora, puedes verificar tu instalación abriendo https://example.com en tu navegador web. Aparecerá la siguiente página indicando que la instalación se ha realizado correctamente.

Página fantasma

Paso 10 – Finalizar la configuración

Para finalizar la configuración de tu blog Ghost, visita https://example.com/ghost en tu navegador. El /ghost adicional al final del dominio de tu blog te redirige al Panel de administración de Ghost o, en este caso, a la configuración, ya que estás accediendo a ella por primera vez.

Aquí se te pedirá que crees tu cuenta de Administrador y que elijas un título para el blog.

Detalles de la configuración fantasma

Introduce tus datos y haz clic en el botón Crear cuenta y empezar a publicar para continuar.

A continuación, accederás a la siguiente pantalla, donde se te ofrecen opciones como escribir tu primera entrada, personalizar tu sitio e importar miembros.

Sugerencias del instalador de Ghost

Elegiremos el administrador Explorar Ghost para explorar e ir directamente al panel de control. Al final de la configuración, te aparecerá el panel de administración de Ghost.

Panel de administración de Ghost

Si quieres cambiar al modo oscuro, puedes hacerlo haciendo clic en el interruptor situado junto al botón de engranaje de configuración, en la parte inferior de la página de configuración.

Conmutar Modo Oscuro Fantasma

Verás una publicación predeterminada. Puedes despublicarla o eliminarla y empezar a publicar.

Panel de Puestos Fantasma

Paso 11 – Configurar el Mailer

Ghost no sólo actúa como plataforma de blogs, sino también como gestor de boletines. Para las operaciones cotidianas, puedes utilizar cualquier servicio de correo transaccional que funcione con Ghost para enviar correos. Pero si quieres enviar boletines a través de Ghost, el único servicio de correo masivo oficial compatible es Mailgun. También puedes utilizar otro servicio de boletines, pero para ello tendrás que utilizar la función de integración Zapier de Ghost.

Configuremos primero un servicio SMTP para correos transaccionales. Para ello, abre el archivo /var/www/html/ghost/config.production.json para editarlo.

$ nano /var/www/html/ghost/config.production.json

Busca las siguientes líneas.

 "mail": {
    "transport": "Direct"
  },

Sustitúyelas por el siguiente código.

"mail": {
    "from": "'HowtoForge Support' [email protected]",
    "transport": "SMTP",
    "options": {
        "host": "YOUR-SES-SERVER-NAME",
        "port": 465,
        "service": "SES",
        "auth": {
            "user": "YOUR-SES-SMTP-ACCESS-KEY-ID",
            "pass": "YOUR-SES-SMTP-SECRET-ACCESS-KEY"
        }
    }
},

Aquí estamos utilizando el servicio Amazon SES Mail ya que es asequible y no requiere cuotas mensuales.

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite. Una vez que hayas terminado, reinicia la aplicación Ghost para que los cambios surtan efecto.

$ ghost restart

Para configurar los ajustes del boletín de noticias, visita la sección Configuración >> Boletín de noticias por correo electrónico.

Configuración del boletín Ghost Email

Haz clic en el enlace Configuración de Mailgun para expandirlo.

Introduce tu Región Mailgun, dominio y clave API.

Configuración del boletín Ghost MailGun

Haz clic en el botón Guardar de la parte superior derecha para guardar la configuración.

Para probar la entrega del boletín, crea una nueva publicación de prueba, pulsa publicar y selecciona la opción Sólo correo electrónico. Si quieres publicar también el post, selecciona la opción Publicar y enviar por correo electrónico.

Opción de publicar/enviar correos fantasma

Pulsa el botón Continuar, revisión final para continuar. La siguiente página te pedirá de nuevo la confirmación final.

Fantasma Enviar Boletín Email Confirmar

Haz clic en el botón Enviar correo electrónico, ahora mismo para enviar el boletín. Recibirás el siguiente mensaje una vez enviado el correo.

Mensaje de entrega satisfactoria de Ghost Newsletteter

Comprueba tu correo electrónico para ver si se ha enviado.

Boletín Fantasma Email

Paso 12 – Actualizar Ghost

Hay dos tipos de actualizaciones de Ghost: actualizaciones menores y actualizaciones mayores.

Primero, haz una copia de seguridad completa si quieres ejecutar una actualización menor. Crea una copia de seguridad de todos los mensajes, miembros, temas, imágenes, archivos y archivos de redirección.

$ cd /var/www/html/ghost
$ ghost backup

Ejecuta el comando actualizar para realizar la actualización menor.

$ ghost update

Para realizar una actualización mayor, debes seguir la guía oficial de actualización detallada en Ghost. Dependiendo de la versión en la que te encuentres y de la versión mayor a la que quieras actualizar, los pasos variarán.

Conclusión

Con esto concluye nuestro tutorial sobre cómo configurar Ghost CMS en tu servidor Debian 12 utilizando Nginx. Si tienes alguna pregunta o comentario, compártelos en los comentarios a continuación.

También te podría gustar...