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.
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.
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.
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.
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.
Cambia a la página Publicaciones y verás una publicación predeterminada. Puedes despublicarla o eliminarla y empezar a publicar.
)
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.
Haz clic en el enlace Configuración de Mailgun para expandirlo.
Introduce tu Región Mailgun, dominio y clave API.
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.