Blogging · 13 min read · Oct 23, 2025

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 con apariencia profesional. Se lanzó en 2013 como una alternativa a WordPress. Está escrito en JavaScript y es impulsado por la biblioteca Node.js.

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

Prerrequisitos

  • Un servidor que ejecute Debian 12 con un mínimo de 2GB de RAM.
  • Un usuario no root con privilegios de sudo.
  • Un Nombre de Dominio Totalmente Calificado (FQDN) como example.com apuntando a tu servidor.
  • Asegúrate de que todo esté actualizado. $ sudo apt update $ sudo apt upgrade
  • Algunos paquetes que tu sistema necesita. $ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y Algunos de estos paquetes pueden ya estar instalados en tu sistema.

Paso 1 - Configurar el Firewall UFW

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

Verifica si el firewall está en funcionamiento.

$ sudo ufw status

Deberías obtener la siguiente salida.

Estado: inactivo

Permite el puerto SSH para que el firewall no interrumpa la conexión actual al habilitarlo.

$ sudo ufw allow OpenSSH

Permite también los puertos HTTP y HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Habilita el Firewall

$ sudo ufw enable
El comando puede interrumpir las conexiones ssh existentes. ¿Proceder con la operación (y|n)? y
El firewall está activo y habilitado al inicio del sistema

Verifica el estado del firewall nuevamente.

$ sudo ufw status

Deberías ver una salida similar.

Estado: activo

Para                         Acción      Desde
--                         ------      ----
OpenSSH                    PERMITIR   En cualquier lugar
80/tcp                     PERMITIR   En cualquier lugar
443                        PERMITIR   En cualquier lugar
OpenSSH (v6)               PERMITIR   En cualquier lugar (v6)
80/tcp (v6)                PERMITIR   En cualquier lugar (v6)
443 (v6)                   PERMITIR   En cualquier lugar (v6)

Paso 2 - Instalar Nginx

Debian 12 viene con una versión más antigua de Nginx. Para instalar la última versión, necesitas 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

Agrega el repositorio para 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. El sudo es necesario 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

El instalador de Ghost 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 LTS (Soporte a Largo Plazo) actual 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 usando Docker

Debian ya no incluye MySQL. En su lugar, incluye MariaDB. Ghost solo admite MySQL. Puedes ajustar Ghost para que funcione con MariaDB, pero no se recomienda. Dado que los repositorios oficiales de MySQL no se han actualizado para Debian 12 al momento de escribir este tutorial, lo instalaremos usando 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 de 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 deseas evitar usar sudo cada vez que ejecutes el comando docker, agrega tu nombre de usuario al grupo docker.

$ sudo usermod -aG docker $(whoami)

Necesitarás cerrar sesión del servidor y volver a iniciar sesión como el mismo usuario para habilitar este cambio o usar el siguiente comando.

$ su - ${USER}

Confirma que tu usuario ha sido agregado al grupo Docker.

$ groups
navjot wheel docker

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

$ mkdir ~/mysql

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

$ nano docker-compose.yml

Pega el siguiente código en él.

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 presionando Ctrl + X y entrando Y cuando se te solicite.

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

Inicia el contenedor de MySQL.

$ docker compose up -d

Verifica el estado del contenedor de 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 de MySQL usando el puerto 3306 y realizar operaciones en él.

Paso 5 - Instalar Ghost

Podemos instalar Ghost usando Docker también, 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 actualizaciones del blog 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

Preparar 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

Instalar Ghost es un proceso de un solo comando.

$ ghost install

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

  • URL del Blog: Ingresa tu URL completa del blog junto con el protocolo https. ( https://example.com)
  • Nombre de Host de MySQL: Presiona Enter para usar el valor predeterminado de localhost ya que nuestra instalación de Ghost y MySQL están en el mismo servidor.
  • Nombre de Usuario de MySQL: Ingresa ghost como tu nombre de usuario de MySQL.
  • Contraseña de MySQL: Ingresa tu contraseña de root creada anteriormente en el archivo docker.
  • Nombre de la base de datos Ghost: Ingresa el nombre de la base de datos ( ghostdb) configurada en el archivo docker.
  • Contraseña de Sudo: Se te pedirá tu contraseña de sudo para realizar tareas administrativas.
  • ¿Configurar Nginx?: Por lo general, Ghost-CLI detecta tu instalación de Nginx y la configura automáticamente para tu blog. Pero eso solo funciona para Nginx instalado usando el paquete del SO. Dado que lo instalamos usando el repositorio de Nginx, Ghost no puede detectarlo y lo omitirá automáticamente.
  • ¿Configurar SSL?: Dado que omitió la configuración de Nginx, la herramienta CLI también omitirá la configuración de un SSL.
  • ¿Configurar systemd?: Ghost preguntará si deseas configurar un servicio del sistema para Ghost. Presiona Y para continuar.
  • ¿Iniciar Ghost?: Presiona Y para iniciar tu 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 lleva 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

Usa el siguiente comando para asegurarte de que el comando Certbot pueda ejecutarse 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 en tu servidor.

Genera un certificado de grupo Diffie-Hellman.

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

Verifica el servicio programador de renovación 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 prueba del proceso para verificar si la renovación de SSL está funcionando correctamente.

$ sudo certbot renew --dry-run

Si no ves errores, estás listo. Tu certificado se renovará automáticamente.

Paso 7 - Configurar Nginx

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

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

Pega el siguiente código en el archivo ghost.conf. Reemplaza todas las instancias de example.com con 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 solicitudes HTTP a HTTPS y servirá como un proxy para el servicio Ghost para servirlo a través de tu dominio.

Guarda el archivo presionando Ctrl + X y entrando Y cuando se te solicite.

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

$ sudo nano /etc/nginx/nginx.conf

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

server_names_hash_bucket_size  64;

Guarda el archivo presionando Ctrl + X y entrando Y cuando se te solicite.

Verifica tu configuración de Nginx.

$ sudo nginx -t

Si no ves errores, significa que estás listo para continuar. Reinicia el servidor Nginx para aplicar la configuración.

$ sudo systemctl restart nginx

Paso 9 - Ejecutar el Sitio

Ahora, puedes verificar tu instalación abriendo https://example.com en tu navegador web. Obtendrás la siguiente página que indica una instalación exitosa.

Página de inicio de Ghost

Paso 10 - Completar la Configuración

Para terminar de configurar tu blog Ghost, visita https://example.com/ghost en tu navegador. El extra /ghost 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 lo estás accediendo por primera vez.

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

Detalles de configuración de Ghost

Ingresa tus detalles y haz clic en el botón Crear cuenta y comenzar a publicar para continuar.

A continuación, serás llevado a la siguiente pantalla donde se te dan opciones como escribir tu primera publicación, personalizar tu sitio e importar miembros.

Sugerencias del instalador de Ghost

Elegiremos Explorar la administración de Ghost para explorar e ir directamente al panel de control. Al final de la configuración, serás recibido con el panel de administración de Ghost.

Panel de administración de Ghost

Si deseas cambiar a modo oscuro, puedes hacerlo haciendo clic en el interruptor 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 comenzar a publicar.

Panel de publicaciones de Ghost

Paso 11 - Configurar el Correo

Ghost no solo actúa como una plataforma de blogs, sino también como un gestor de boletines. Para operaciones diarias, puedes usar cualquier servicio de correo transaccional para trabajar con Ghost para enviar correos. Pero si deseas enviar boletines a través de Ghost, el único servicio de correo masivo oficial admitido es Mailgun. También puedes usar un servicio de boletines diferente, pero para eso necesitarás usar la función de integración de Zapier de Ghost.

Primero configuremos un servicio SMTP para correos transaccionales. Para esto, abre el archivo /var/www/html/ghost/config.production.json para editar.

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

Encuentra las siguientes líneas.

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

Reemplázalas con el siguiente código.

"mail": {
    "from": "'Soporte de HowtoForge' [email protected]",
    "transport": "SMTP",
    "options": {
        "host": "NOMBRE-DE-TU-SERVIDOR-SES",
        "port": 465,
        "service": "SES",
        "auth": {
            "user": "TU-ID-DE-CLAVE-DE-ACCESO-SMTP-SES",
            "pass": "TU-CLAVE-DE-ACCESO-SECRETOS-SMTP-SES"
        }
    }
},

Aquí estamos utilizando el servicio de correo de Amazon SES ya que es asequible y no requiere tarifas mensuales.

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

$ ghost restart

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

Configuración del boletín de correo electrónico de Ghost

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

Completa tu Región de Mailgun, dominio y clave API.

Configuración del boletín de MailGun de Ghost

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

Para probar la entrega del boletín, crea una nueva publicación de prueba, presiona publicar y selecciona la opción Solo correo. Si deseas publicar la publicación también, selecciona la opción Publicar y enviar correo.

Opción de Publicar/Enviar Correo de Ghost

Haz clic en el botón Continuar, revisión final para proceder. La siguiente página pedirá nuevamente la confirmación final.

Confirmar envío de boletín de correo de Ghost

Haz clic en el botón Enviar correo, ahora mismo para enviar el boletín. Recibirás el siguiente mensaje una vez que se envíe el correo.

Mensaje de entrega exitosa del boletín de Ghost

Verifica tu correo electrónico para la publicación.

Correo del boletín de Ghost

Paso 12 - Actualizar Ghost

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

Primero, realiza una copia de seguridad completa si deseas ejecutar una actualización menor. Crea una copia de seguridad de todas las publicaciones, miembros, temas, imágenes, archivos y archivos de redirección.

$ 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 de actualización detallada oficial en Ghost. Dependiendo de qué versión estés actualmente y la versión mayor a la que deseas actualizar, los pasos variarán.

Conclusión

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

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.