Ghost CMS, Arquitectura e Implementación con Docker
Manual técnico completo para comprender, configurar y desplegar Ghost CMS en un entorno de producción usando contenedores Docker.
1. ¿Qué es Ghost CMS y cómo funciona?
Ghost es un sistema de gestión de contenidos (CMS) de código abierto (*Open Source*) de última generación, desarrollado sobre Node.js. Fue concebido como una alternativa ultrarrápida, ligera y centrada 100% en la publicación de contenidos, boletines informativos (newsletters) y modelos de membresía/suscripción.
Arquitectura y Componentes Clave
- Backend (Node.js + Express):** Procesa las peticiones HTTP con altísima concurrencia y bajo consumo de memoria RAM.
- ORM y Base de Datos (Bookshelf.js / Knex + MySQL 8):** Almacena de forma relacional y estructurada usuarios, entradas, configuraciones y etiquetas. En producción, Ghost exige el uso exclusivo de MySQL 8.0.
- Capa de Renderizado Frontend (Handlebars .hbs):** Motor de plantillas dinámico que renderiza HTML en el servidor de forma instantánea.
- Arquitectura Headless (Content API y Admin API):** Permite desacoplar el frontend para consumir el contenido desde aplicaciones móviles o frameworks modernos como Next.js, Nuxt o Astro.
- Editor de Contenidos (Koenig Editor):** Guarda las entradas en formato estructurado JSON (MobileDoc/Lexical), asegurando la compatibilidad limpia entre web, emails y aplicaciones.
Enlaces Oficiales y Recursos
- 🌐 Sitio Web Oficial de Ghost
- 📖 Documentación para Desarrolladores
- 💻 Repositorio Oficial en GitHub
- 💬 Foro Oficial de la Comunidad
2. Requisitos Previos del Sistema
- Servidor VPS con Linux (Ubuntu 22.04 LTS / 24.04 LTS recomendado).
- Mínimo 1 GB de memoria RAM (2 GB recomendados para procesos de actualización).
- Docker Engine y Docker Compose V2 instalados.
- Un dominio o subdominio con un registro DNS tipo A apuntando a la IP pública del servidor.
- Un Proxy Inverso (Nginx, Traefik o Caddy) para la terminación SSL (HTTPS).
3. Explicación Detallada de Variables de Entorno (.env)
A continuación se detallan todas las variables de entorno críticas necesarias para orquestar la pila de servicios en Docker:
| Variable | Tipo / Formato | Descripción y Función Técnica |
|---|---|---|
GHOST_URL |
URL (https://...) |
CRÍTICA. La URL pública exacta donde se servirá el sitio. Define cómo se forman las URLs absolutas, imágenes, etiquetas rel y cookies de sesión en el panel /ghost. |
GHOST_PORT |
Puerto (ej. 2368) |
Puerto interno expuesto por la aplicación en el host para conectarse con el proxy inverso Nginx. |
MYSQL_ROOT_PASSWORD |
Texto / Secreto | Contraseña maestra del administrador de MySQL. Usada para crear la base de datos inicial y administrar el motor. |
MYSQL_DATABASE |
Texto (ej. ghost_prod) |
Nombre de la base de datos relacional creada dentro del contenedor de MySQL. |
MYSQL_USER |
Texto | Usuario sin privilegios de root que utilizará el backend de Ghost para sus operaciones CRUD cotidianas. |
MYSQL_PASSWORD |
Texto / Secreto | Contraseña de acceso para el usuario limitado de Ghost en MySQL. |
MAIL_HOST |
Hostname SMTP | Servidor de salida SMTP (ej. smtp.mailgun.org, smtp.sendgrid.net) para correos transaccionales del sistema. |
MAIL_PORT |
Puerto (ej. 587) |
Puerto de conexión SMTP. El puerto 587 usa STARTTLS y es el estándar de la industria. |
MAIL_USER |
Usuario SMTP | Nombre de usuario autenticado en la plataforma del proveedor de correo electrónico. |
MAIL_PASS |
Contraseña / API Key | Credencial de autenticación o token de la API SMTP. |
4. Archivos de Configuración Completo
Creación de la Estructura de Trabajo en Bash
BASHTerminal
# Crear directorio del proyecto
mkdir -p /opt/ghost-docker
cd /opt/ghost-docker
1. Archivo de Variables de Entorno: .env
ENV.env
# =================================-------------------
# CONFIGURACIÓN GENERAL DE GHOST
# =================================-------------------
GHOST_URL=https://danielasbun.page
GHOST_PORT=2368
# =================================-------------------
# CONFIGURACIÓN DE BASE DE DATOS (MYSQL 8.0)
# =================================-------------------
MYSQL_ROOT_PASSWORD=SuperRootSecretPassword2026!
MYSQL_DATABASE=ghost_production
MYSQL_USER=ghost_db_user
MYSQL_PASSWORD=GhostUserSecretPassword2026!
# =================================-------------------
# CONFIGURACIÓN CORREO TRANSACCIONAL (SMTP)
# =================================-------------------
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USER=postmaster@danielasbun.page
MAIL_PASS=3a8f192b0c9e123456789abcdef
2. Archivo de Orquestación: docker-compose.yml
YAMLdocker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0
container_name: ghost_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- ghost_net
ghost:
image: ghost:5-alpine
container_name: ghost_app
restart: always
depends_on:
- db
ports:
- "127.0.0.1:${GHOST_PORT}:2368"
environment:
# URL pública
url: ${GHOST_URL}
# Conexión a Base de Datos
database__client: mysql
database__connection__host: db
database__connection__user: ${MYSQL_USER}
database__connection__password: ${MYSQL_PASSWORD}
database__connection__database: ${MYSQL_DATABASE}
# Configuración SMTP
mail__transport: SMTP
mail__options__host: ${MAIL_HOST}
mail__options__port: ${MAIL_PORT}
mail__options__auth__user: ${MAIL_USER}
mail__options__auth__pass: ${MAIL_PASS}
volumes:
- ghost_content:/var/lib/ghost/content
networks:
- ghost_net
volumes:
db_data:
ghost_content:
networks:
ghost_net:
driver: bridge
3. Configuración del Proxy Inverso: Nginx (ghost.conf)
NGINX/etc/nginx/sites-available/ghost.conf
server {
listen 80;
server_name danielasbun.page;
location / {
proxy_pass http://127.0.0.1:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
5. Paso a Paso para la Ejecución del Despliegue
Paso 1: Habilitar el sitio en Nginx y obtener Certificado SSL
BASHTerminal
# Enlazar sitio
sudo ln -s /etc/nginx/sites-available/ghost.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Obtener certificado SSL gratuito con Let's Encrypt / Certbot
sudo certbot --nginx -d danielasbun.page
Paso 2: Desplegar el Stack de Docker
BASHTerminal
# Iniciar los contenedores en segundo plano
cd /opt/ghost-docker
docker compose up -d
Paso 3: Verificación y Monitoreo
BASHTerminal
# Estado de los contenedores
docker compose ps
# Monitorear logs del inicio de Ghost
docker compose logs -f ghost
6. Mantenimiento y Comandos Útiles
- Actualizar versión de Ghost:
BASHTerminal
docker compose pull docker compose up -d - Respaldo de Base de Datos:
BASHTerminal
docker exec ghost_db mysqldump -u root -p${MYSQL_ROOT_PASSWORD} ghost_production > backup_ghost.sql - Respaldo de Archivos e Imágenes: Copiar el contenido almacenado en el volumen persistente
ghost_content.