Cómo desplegar Ghost CMS en Rocky Linux 9

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 porque se estaba volviendo demasiado complejo. Está escrito en JavaScript y funciona con la biblioteca Node.js.

Este tutorial explorará cómo instalar Ghost CMS utilizando Nginx y MySQL en un servidor con Rocky Linux 9. Utilizaremos el servidor Nginx para alojar el blog y el certificado SSL Let’s Encrypt para proteger nuestra instalación.

Requisitos previos

  • Un servidor con Rocky Linux 9.
  • Un usuario no root con privilegios sudo.
  • Un nombre de dominio completo (FQDN) que apunte a tu servidor. Para nuestros propósitos, utilizaremos ghost.example.com como nombre de dominio.
  • Asegúrate de que todo está actualizado.
    $ sudo dnf update
    
  • Instala los paquetes de utilidades básicas. Es posible que algunos de ellos ya estén instalados.
    $ sudo dnf install wget curl nano unzip yum-utils -y
    

Paso 1 – Configurar el Cortafuegos

El primer paso es configurar el cortafuegos. Rocky Linux utiliza el cortafuegos Firewalld. Comprueba el estado del cortafuegos.

$ sudo firewall-cmd --state
running

El cortafuegos funciona con diferentes zonas, y la zona pública es la que utilizaremos por defecto. Enumera todos los servicios y puertos activos en el cortafuegos.

$ sudo firewall-cmd --permanent --list-services

Debería mostrar la siguiente salida.

cockpit dhcpv6-client ssh

Wiki.js necesita los puertos HTTP y HTTPS para funcionar. Ábrelos.

$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent

Recarga el cortafuegos para aplicar los cambios.

$ sudo firewall-cmd --reload

Paso 2 – Instalar Nginx

Rocky Linux 9 viene con una versión antigua de Nginx. Necesitas descargar el repositorio oficial de Nginx para instalar la última versión.

Crea y abre el archivo /etc/yum.repos.d/nginx.repo para crear el repositorio oficial de Nginx.

$ sudo nano /etc/yum.repos.d/nginx.repo

Pega en él el siguiente código.

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

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

Instala el servidor Nginx.

$ sudo dnf install nginx -y

Verifica la instalación.

$ nginx -v
nginx version: nginx/1.22.1

Habilita e inicia el servidor Nginx.

$ sudo systemctl enable nginx --now

Comprueba el estado del servidor.

$ sudo systemctl status nginx
? nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
     Active: active (running) since Tue 2022-10-25 08:27:47 UTC; 2s ago
       Docs: http://nginx.org/en/docs/
    Process: 1650 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
   Main PID: 1651 (nginx)
      Tasks: 2 (limit: 5912)
     Memory: 1.9M
        CPU: 7ms
     CGroup: /system.slice/nginx.service
             ??1651 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ??1652 "nginx: worker process"

Oct 25 08:27:47 ghost.example.com systemd[1]: Starting nginx - high performance web server...

Paso 3 – Instalar Node.js

Ghost Installer necesita Nodejs para funcionar. Ejecuta los siguientes comandos para instalar Node 16.

$ curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -

Instala Node.

$ sudo dnf install -y nodejs

Verifica la instalación de Node.

$ node --version
v16.18.0

En el momento de escribir este tutorial, Node 18 ya está disponible y es la versión LTS. Ghost aún no ha añadido soporte para ella. Consulta el documento de Ghost sobre versiones de Node para conocer la última versión de Node soportada. Cuando Ghost añada soporte para Node 18, instala Node 18 utilizando los siguientes comandos.

$ curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
$ sudo dnf install -y nodejs

Paso 4 – Instalar MySQL

Rocky Linux 9 incluye la última versión de MySQL. Puedes instalarla con un solo comando.

$ sudo dnf install mysql-server

Comprueba la versión de MySQL.

$ mysql --version
mysql  Ver 8.0.30 for Linux on x86_64 (Source distribution)

Activa e inicia el servicio MySQL.

$ sudo systemctl enable mysqld --now

Comprueba el estado del servicio.

$ sudo systemctl status mysqld
? mysqld.service - MySQL 8.0 database server
     Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
     Active: active (running) since Tue 2022-10-25 09:00:26 UTC; 3s ago
    Process: 2920 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
    Process: 2942 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)
   Main PID: 3021 (mysqld)
     Status: "Server is operational"
      Tasks: 39 (limit: 5912)
     Memory: 404.4M
        CPU: 4.686s
     CGroup: /system.slice/mysqld.service
             ??3021 /usr/libexec/mysqld --basedir=/usr

Oct 25 09:00:18 ghost.example.com systemd[1]: Starting MySQL 8.0 database server...
Oct 25 09:00:18 ghost.example.com mysql-prepare-db-dir[2942]: Initializing MySQL database
Oct 25 09:00:26 ghost.example.com systemd[1]: Started MySQL 8.0 database server.

Puedes acceder al intérprete de comandos de MySQL utilizando la autenticación Unix por defecto. Pero no puedes ejecutar el asistente de configuración de seguridad. Por lo tanto, el siguiente paso es necesario para las versiones de MySQL 8.0.28 y superiores. Entra en el intérprete de comandos de MySQL.

$ sudo mysql

Ejecuta el siguiente comando para establecer la contraseña de tu usuario root. Asegúrate de que tiene una mezcla de números, mayúsculas, minúsculas y caracteres especiales.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword12!';

Sal del intérprete de comandos. La advertencia de este paso es que ya no podrás iniciar sesión en el intérprete de comandos MySQL utilizando la autenticación Unix.

mysql> exit

Ejecuta el script de instalación segura de MySQL.

$ sudo mysql_secure_installation

Se te pedirá que instales el Componente Validar Contraseña. Éste comprueba la seguridad de las contraseñas utilizadas en MySQL. Pulsa Y para instalarlo.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: Y

A continuación, se te pedirá que establezcas el nivel de la política de validación de contraseñas. Elige 2, ya que es el más fuerte. A continuación se te pedirá que crees una contraseña de root. Introduce una contraseña con los requisitos indicados. Y cuando se te pregunte si quieres continuar con la contraseña, pulsa Y para continuar.

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
Please set the password for root here.

New password: 

Re-enter new password: 

Estimated strength of the password: 100 
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Por último, pulsa Y para eliminar los usuarios anónimos, desautorizar los inicios de sesión remotos de root, eliminar la base de datos de prueba y recargar las tablas de privilegios.

By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.

All done!

Esto completa el proceso de instalación y seguridad de MySQL.

Paso 5 – Instalar Ghost

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. Ignora cualquier advertencia que recibas durante el proceso.

$ 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

Asigna 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á una serie de preguntas para configurar el blog.

  • En el momento de escribir este tutorial, Ghost-CLI no admite ningún otro SO aparte de Ubuntu. Te preguntará si quieres continuar con la instalación. Pulsa Y para continuar.
  • URLdel blog: Introduce la URL completa de tu blog junto con el protocolo https. (https://ghost.example.com)
  • Nombre de 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 root como nombre de usuario de MySQL.
  • Contraseña de MySQL: Introduce tu contraseña de root creada anteriormente.
  • Nombre de la base de datos de Ghost: Dale un nombre a tu base de datos de Ghost. (ghostdb)
  • Contraseñasudo: Introduce la contraseña sudo de tu sistema para realizar comandos elevados.
  • ¿Instalarun usuario MySQL fantasma?: El instalador te preguntará si quieres crear un usuario MySQL independiente para Ghost. Pulsa Y para continuar.
  • ¿CrearNginx? Normalmente, Ghost-CLI detecta tu instalación de Nginx y la configura automáticamente para tu blog. Pero por ahora, no puede detectar nuestra instalación de Nginx. Por lo tanto, el instalador omitirá automáticamente este paso. Configuraremos Nginx manualmente.
  • ConfigurarSSL?: Al haberse saltado la configuración de Nginx, la herramienta CLI también se saltará la configuración de un 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. El servicio se iniciará, pero tendremos que configurar Nginx y SSL para que funcione.

Paso 6 – Instalar SSL

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

Para instalar Certbot, utilizaremos el instalador de paquetes Snapd. Snapd siempre lleva la última versión estable de Certbot, que es la que debes utilizar.

La herramienta Snapd necesita el repositorio Epel para funcionar.

$ sudo dnf install epel-release -y

Utilizaremos Snapd para instalar Certbot. Instala Snapd.

$ sudo dnf install snapd -y

Habilita e Inicia el servicio Snap.

$ sudo systemctl enable snapd.socket --now

Crea los enlaces necesarios para que Snapd funcione.

$ sudo ln -s /var/lib/snapd/snap /snap
$ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh

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

Asegúrate 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

Genera un certificado SSL.

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

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

Genera un certificado de grupo Diffie-Hellman.

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

Realiza un simulacro 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 ghost.example.com por tu dominio.

## enforce HTTPS
server {
  listen 80;
  listen [::]:80;
  server_name ghost.example.com;
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name ghost.example.com;

  access_log /var/log/nginx/ghost.access.log;
  error_log /var/log/nginx/ghost.error.log;
  client_max_body_size 20m;

  http2_push_preload on; # Enable HTTP/2 Server Push

  ssl_certificate     /etc/letsencrypt/live/ghost.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/ghost.example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/ghost.example.com/chain.pem;
  ssl_session_timeout 1d;

  # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
  ssl_protocols TLSv1.2 TLSv1.3;

  # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
  # prevent replay attacks.
  #
  # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
  ssl_early_data on;

  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
  ssl_prefer_server_ciphers on;
  ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets off;

  # OCSP Stapling ---
  # fetch OCSP records from URL in ssl_certificate and cache them
  ssl_stapling on;
  ssl_stapling_verify on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  add_header X-Early-Data $tls1_3_early_data;

  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;
  }
}

# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
  "~." $ssl_early_data;
  default "";
}

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. Vuelve a cargar el servidor Nginx.

$ sudo systemctl reload nginx

Paso 8 – Configurar SELinux

Permite que Nginx se conecte a la red.

$ sudo setsebool -P httpd_can_network_connect 1

Paso 9 – Ejecutar el sitio

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

Página fantasma

Paso 10 – Completa la configuración

Para terminar de configurar tu blog Ghost, visita https://ghost.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.

Tendrás que crear tu cuenta de Administrador y elegir un título de 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

Cambia a la página Publicaciones y 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": "'Acme 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 muy barato y gratuito de por vida si estás utilizando su servicio EC2.

Si quieres utilizar su servicio de newsletter utilizando Mailgun, introduce el siguiente código en su lugar.

"mail": {
  "from": "'Acme Support' [email protected]",
  "transport": "SMTP",
  "options": {
    "service": "Mailgun",
    "host": "smtp.mailgun.org",
    "port": 587,
    "secure": true,
    "auth": {
      "user": "[email protected]",
      "pass": "1234567890"
    }
  }
},

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

Cuando 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 electrónico fantasma

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 el envío del boletín, abre cualquier entrada, despliega su configuración y haz clic en la opción Boletín por correo electrónico. A continuación, envía un correo electrónico de prueba para comprobar si funciona. Si no recibes ningún error, significa que el envío del boletín funciona.

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.

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

Ejecuta el comando de actualización 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 Rocky Linux 9 utilizando Nginx. Si tienes alguna pregunta o comentario, compártelos en los comentarios a continuación.

También te podría gustar...