Ghost Docker Compose es una de las formas mas practicas de montar un blog profesional self-hosted con control total sobre tu contenido, rendimiento y costes. En esta guia paso a paso vas a desplegar Ghost con Docker Compose, base de datos MySQL, configuracion segura y estrategia de backup para produccion. Si ya sigues otros tutoriales del blog, tienes mas guias en la categoria Docker Compose y ejemplos como Mattermost Docker Compose.
Que es Ghost Docker Compose y por que usarlo
Ghost es un CMS moderno orientado a publicacion, newsletter y membresias. A diferencia de un stack mas pesado, esta pensado para escribir rapido, publicar contenido limpio y escalar con buena experiencia de usuario. Desplegarlo con Ghost Docker Compose te permite encapsular servicios, versionar configuracion en Git y mover el entorno entre servidores sin friccion. En lugar de instalar paquetes manualmente en el sistema operativo, defines un fichero declarativo y levantas todo con comandos reproducibles.
El enfoque con contenedores tambien ayuda a separar responsabilidades: un contenedor para Ghost, otro para MySQL, volumenes para persistencia y una red privada para comunicacion interna. Esto simplifica mantenimiento, rollback y actualizaciones. Recursos oficiales: Ghost Docs, GitHub de Ghost y Docker Compose docs.
Arquitectura recomendada para Ghost Docker Compose
En una arquitectura tipica con Ghost Docker Compose tienes cuatro piezas: 1) contenedor Ghost, 2) contenedor MySQL 8, 3) volumen para contenido de Ghost (themes, imagenes, configuracion), 4) volumen para datos de MySQL. Ademas, defines una red interna para que Ghost se conecte a la base de datos por nombre de servicio y no por IP fija.
Para produccion, es recomendable exponer Ghost solo a traves de un proxy inverso (Nginx Proxy Manager, Traefik o Caddy) que gestione TLS. Asi mantienes el contenedor de la aplicacion aislado y concentras certificados SSL en el proxy. El flujo es: usuario -> proxy HTTPS -> Ghost -> MySQL. Con esto consigues aislamiento, observabilidad y renovacion automatica de certificados sin tocar la app.
Requisitos previos para Ghost Docker Compose
Antes de desplegar Ghost Docker Compose, prepara: servidor Linux actualizado (Ubuntu 22.04 o similar), Docker Engine y plugin de Compose instalados, dominio apuntando al servidor, puertos 80/443 abiertos si usas proxy con HTTPS, y al menos 2 GB RAM recomendados para ir holgado con MySQL. Tambien te conviene tener nociones de logs, variables de entorno y gestion basica de redes Docker.
Instala Docker desde fuentes oficiales y valida versiones:
docker --version
docker compose version
Si vas a usar proxy inverso externo, define desde el inicio la URL canonica de tu sitio (por ejemplo https://blog.tudominio.com) porque Ghost depende de ese valor para enlaces internos, redirecciones y assets.
Preparar entorno y variables de Ghost Docker Compose
Crea una carpeta de proyecto y un archivo .env para evitar hardcodear secretos en el compose. Este paso es clave en Ghost Docker Compose porque separa configuracion sensible del manifiesto principal y facilita cambios por entorno (dev, staging, prod).
mkdir -p /opt/ghost
cd /opt/ghost
cat > .env <<'ENV'
GHOST_URL=https://blog.tudominio.com
MYSQL_ROOT_PASSWORD=super_root_password_largo
MYSQL_DATABASE=ghost
MYSQL_USER=ghost
MYSQL_PASSWORD=super_password_largo
TZ=Europe/Madrid
ENV
Buenas practicas: contrasenas largas (minimo 24 caracteres), no reutilizar claves, y permisos de archivo estrictos en .env (chmod 600 .env). Si gestionas varios nodos, guarda secretos en un gestor seguro y no en repositorios publicos.
docker-compose.yml completo de Ghost Docker Compose
Este ejemplo de Ghost Docker Compose es funcional y preparado para uso real, con healthchecks, restart policy y volumenes persistentes:
services:
ghost:
image: ghost:5-alpine
container_name: ghost_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
url: ${GHOST_URL}
database__client: mysql
database__connection__host: db
database__connection__user: ${MYSQL_USER}
database__connection__password: ${MYSQL_PASSWORD}
database__connection__database: ${MYSQL_DATABASE}
mail__transport: SMTP
mail__options__service: Mailgun
TZ: ${TZ}
ports:
- "2368:2368"
volumes:
- ghost_content:/var/lib/ghost/content
networks:
- ghost_net
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:2368/ghost/"]
interval: 30s
timeout: 10s
retries: 5
db:
image: mysql:8.0
container_name: ghost_db
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
TZ: ${TZ}
volumes:
- ghost_db_data:/var/lib/mysql
networks:
- ghost_net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 20s
timeout: 10s
retries: 10
volumes:
ghost_content:
ghost_db_data:
networks:
ghost_net:
driver: bridge
Con esta base, Ghost Docker Compose queda listo para arrancar con docker compose up -d. Si usas proxy inverso, puedes quitar el mapeo de puertos publico y publicar solo en red interna; depende de tu topologia.
Despliegue paso a paso con Ghost Docker Compose
1) Valida sintaxis del manifiesto:
docker compose config
2) Levanta servicios:
docker compose up -d
3) Comprueba estado:
docker compose ps
docker compose logs -f ghost
4) Abre http://IP:2368/ghost o tu dominio para completar el onboarding. El instalador te pedira crear usuario admin, titulo del sitio y correo. 5) Configura cabeceras y cache en tu proxy para mejorar rendimiento. 6) Activa backups periodicos del contenido y la base de datos. Este flujo con Ghost Docker Compose te deja una instalacion limpia y mantenible desde el primer dia.
Cuando termines el onboarding, revisa Settings en panel de Ghost: idioma, zona horaria, integraciones de email y miembros. Si planeas newsletter, valida DNS de envio y reputacion del dominio para evitar spam folder. Es preferible dejar bien esta parte al inicio porque luego afecta entregabilidad y conversion.
Correo transaccional y entregabilidad
Ghost envía correos para recuperación de contraseña, invitaciones y boletines si activas miembros. En el ejemplo de compose aparecen variables genéricas de SMTP; en producción debes configurar un proveedor serio (SendGrid, Mailgun, Amazon SES, Postmark, etc.), validar SPF, DKIM y DMARC en tu dominio, y usar un remitente coherente con la marca del blog. Sin esto, los correos pueden acabar en spam o no salir nunca. Prueba siempre con una cuenta externa y revisa los logs del contenedor si el envío falla. Si no necesitas correo en la primera fase, puedes simplificar variables y activar SMTP más adelante desde el panel.
Configuracion de proxy y HTTPS para Ghost Docker Compose
Un error comun en Ghost Docker Compose es publicar sin TLS o con URL interna incorrecta. Ghost necesita conocer la URL publica definitiva. Si tu dominio es https://blog.tudominio.com, ese valor debe estar en GHOST_URL. En el proxy inverso, configura forwarding al puerto 2368 del contenedor Ghost y activa certificado TLS valido.
Si usas Caddy, Traefik o Nginx Proxy Manager, manten la regla simple: proxy_pass al servicio Ghost y cabeceras estandar (X-Forwarded-Proto, X-Forwarded-Host). Referencias: configuracion oficial de Ghost y redes en Docker Compose. Con esta capa, Ghost Docker Compose gana seguridad y estabilidad de cara a produccion.
Optimizar rendimiento y seguridad en Ghost Docker Compose
Para rendimiento: limita recursos por servicio, usa imagenes optimizadas y cache en proxy. Evita plugins o integraciones innecesarias que carguen scripts pesados en frontend. En MySQL, vigila uso de RAM y conexiones simultaneas para no saturar instancias pequenas. Un despliegue de Ghost Docker Compose suele ir fluido en VPS medianos si controlas imagenes y consultas.
Para seguridad: aplica actualizaciones periodicas de imagenes, no expongas MySQL fuera de red interna, usa firewall, y rotacion de contrasenas. Si el servidor aloja mas servicios, separa redes Docker por stack para minimizar movimiento lateral. Tambien es recomendable ejecutar comprobaciones de integridad de backups y restauraciones de prueba, no solo generar copias.
Politica de actualizaciones recomendada: entorno staging para probar nuevas versiones, ventana de mantenimiento para produccion y rollback documentado. Con Ghost Docker Compose, actualizar suele ser tan simple como cambiar etiqueta de imagen y recrear contenedor, pero siempre valida compatibilidad de base de datos y estado previo.
Backups y restauracion de Ghost Docker Compose
Un plan minimo de backup para Ghost Docker Compose incluye: dump de MySQL, copia del volumen de contenido y almacenado en destino externo (S3, servidor remoto, almacenamiento cifrado). Haz backups diarios y conserva varias versiones por si detectas corrupcion tarde.
#!/usr/bin/env bash
set -euo pipefail
DATE=$(date +%F-%H%M)
BACKUP_DIR=/opt/ghost/backups/$DATE
mkdir -p "$BACKUP_DIR"
# Dump de base de datos
docker exec ghost_db sh -c 'mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' > "$BACKUP_DIR/ghost.sql"
# Backup de contenido
docker run --rm \
-v ghost_ghost_content:/data \
-v "$BACKUP_DIR":/backup \
alpine tar czf /backup/ghost-content.tar.gz -C /data .
echo "Backup completado en $BACKUP_DIR"
Para restaurar, primero recupera base de datos, luego volumen de contenido y por ultimo reinicia servicios. Este orden evita inconsistencias entre posts y assets. Documenta el procedimiento en tu runbook para que cualquier miembro del equipo pueda ejecutarlo durante una incidencia.
Troubleshooting de Ghost Docker Compose
Error 1: Ghost no conecta con MySQL. Revisa credenciales en .env, nombre del servicio db y healthcheck de MySQL. Comandos utiles: docker compose logs db y docker compose logs ghost. Error 2: redirecciones raras o assets rotos. Normalmente GHOST_URL no coincide con dominio real o falta cabecera X-Forwarded-Proto en proxy. Error 3: puerto ocupado. Cambia mapeo local (por ejemplo 2369:2368) o libera el puerto.
Error 4: rendimiento bajo. Vigila CPU y RAM del host, reduce carga de extensiones externas y aplica cache en proxy. Error 5: base de datos en recovery o bloqueos. Asegura I/O suficiente en disco y revisa logs de MySQL. Un enfoque ordenado de diagnostico en Ghost Docker Compose es: estado de contenedores -> logs -> conectividad de red -> variables -> almacenamiento persistente.
Monitoreo y operacion continua
Una vez en produccion, el trabajo real es mantener disponibilidad y detectar problemas antes de que los vean los lectores. Integra el stack con herramientas que ya conozcas: por ejemplo Uptime Kuma Docker Compose para chequeos HTTP/HTTPS periodicos, o revisa metricas del host con Grafana Docker Compose si exportas datos del sistema. En el dia a dia, los comandos mas utiles son docker compose ps, docker stats y revision de logs filtrados por errores.
Define umbrales claros: tiempo de respuesta del panel admin, ratio de errores 5xx en proxy, espacio libre en disco donde viven los volumenes, y latencia de MySQL. Cuando planifiques ventanas de mantenimiento, anuncialas si el blog tiene audiencia fiel; para cambios de imagen o migraciones, prueba primero en un clon del volumen o en entorno de staging. Documenta versiones de imagen (ghost:5-alpine, mysql:8.0) y la fecha de cada actualizacion para poder correlacionar incidencias con despliegues recientes.
Si expones el sitio a internet, endurece el servidor: SSH solo con claves, fail2ban o equivalente, actualizaciones de seguridad automatizadas donde sea posible, y copias de respaldo cifradas fuera del mismo disco. El contenedor de la base de datos no debe escuchar en interfaces publicas; la red interna de Compose ya ayuda, pero un firewall perimetral refuerza la defensa. Con buena observabilidad y disciplina operativa, el mismo despliegue que montaste con Ghost Docker Compose se mantiene estable meses o años.
Conclusion
Desplegar Ghost Docker Compose te da una plataforma editorial moderna, portable y preparada para crecer. Con una configuracion correcta de URL, proxy HTTPS, volumenes persistentes y backups, puedes operar un blog profesional con baja friccion tecnica. El gran valor esta en la repetibilidad: el mismo stack se levanta en minutos en otro servidor si lo necesitas. Como siguiente paso, integra monitorizacion y alertas para detectar degradaciones antes de que afecten a lectores.
FAQ sobre Ghost Docker Compose
Cuanta RAM necesito para Ghost?
Para proyectos pequenos, 2 GB suelen bastar. Si hay newsletter activa y trafico elevado, 4 GB o mas aportan margen operativo.
Puedo usar SQLite en lugar de MySQL?
Para pruebas locales puede servir, pero en produccion se recomienda MySQL por estabilidad y mantenimiento.
Como actualizo sin perder datos?
Haz backup completo, cambia etiqueta de imagen, ejecuta docker compose pull y docker compose up -d. Verifica logs y acceso al panel tras reinicio.
Es obligatorio usar proxy inverso?
No es obligatorio, pero es la opcion recomendada para TLS, cabeceras, compresion y reglas de seguridad.
Como valido que todo esta correcto?
Comprueba healthchecks, crea un post de prueba, sube imagenes, revisa enlaces y ejecuta una restauracion de backup en entorno temporal.
Puedo poner Ghost detras de Traefik o Caddy?
Si. Ambos son habituales en homelab; configura el upstream al puerto 2368 y las cabeceras de proxy para que la URL publica coincida con GHOST_URL. Guías relacionadas: Traefik Docker Compose y Caddy Docker Compose.
Como migro de otro CMS a Ghost?
Ghost ofrece herramientas e importadores según origen; planifica redirecciones 301, revisa slugs y prueba en staging antes de cortar DNS. Mantén backup del sistema anterior hasta validar indexacion y feeds.
Con este enfoque, Ghost Docker Compose pasa de ser una simple instalacion a convertirse en un servicio robusto y gestionable para contenido serio en 2026.
