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.comapuntando 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 -yAlgunos 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
localhostya que nuestra instalación de Ghost y MySQL están en el mismo servidor. - Nombre de Usuario de MySQL: Ingresa
ghostcomo 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.

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.

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.

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.

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.

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.

Haz clic en el enlace Configuración de Mailgun para expandir.
Completa tu Región de Mailgun, dominio y clave API.

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.

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

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.

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

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.
Recibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.