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.
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.
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.
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": "'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.
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 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.
Pulsa el botón Continuar, revisión final para continuar. La siguiente página te pedirá de nuevo la confirmación final.
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.
Comprueba tu correo electrónico para ver si se ha enviado.
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.