Aprende a migrar tu sitio de Ghost desde una instalación con Ghost CLI a Docker y disfruta de todas las novedades de Ghost 6, incluyendo su nuevo Analytics Web y la integración Social Web con ActivityPub.


En el tutorial de hoy veremos cómo migrar una instalación tradicional de Ghost CLI a una instalación basada en Docker, para aprovechar todas las ventajas y novedades que trae Ghost 6.

Con esta nueva versión, Ghost no solo incorpora una suite de Analytics Web nativa para conocer en tiempo real el rendimiento de tu contenido, sino que también introduce el concepto de Social Web, integrando soporte nativo para ActivityPub. Esto significa que tu publicación podrá ser seguida directamente desde plataformas del Fediverso como Mastodon, Pixelfed o PeerTube, y que tus artículos se convertirán en contenido interactivo que cualquiera podrá comentar o compartir desde su cliente favorito.

A lo largo del proceso explicaremos paso a paso cómo realizar la migración de forma segura, manteniendo tus datos y configuraciones, para que puedas disfrutar de un entorno moderno, flexible y preparado para el futuro de la web abierta.

Requisitos previos

Para seguir este tutorial es importante que:

  • Tengamos una instalación de Ghost instalada a través de Ghost CLI.
  • Acceso a root
  • Un registro en el DNS que apunte al nuevo servidor.

Instalación de Docker

El primer paso que tenemos que hacer, es instalar docker en el mismo servidor donde tenemos funcionando Ghost.

Instalación de Docker en Ubuntu 24.04
Docker es una aplicación que simplifica el proceso de gestión de los procesos de las aplicaciones en contenedores. Los contenedores le permiten ejecutar sus aplicaciones en procesos aislados de recursos.
💡
Si usas otra distribución de GNU/Linux, en el mismo artículo de arriba puedes seleccionar otra distribución.
📢
Es importante también instalar docker-compose ya que lo necesitaremos para el tutorial.

Instalación de Ghost con Docker

El siguiente paso es hacer una instalación nueva de Ghost utilizando Docker, para ello nos descargaremos el repositorio de Ghost que está preparado para ser utilizado con Docker:

git clone https://github.com/TryGhost/ghost-docker.git /opt/ghost && cd /opt/ghost

Haz tu configuración

Copia los ficheros de configuración para luego editarlos a tus necesidades:

cp .env.example .env
cp caddy/Caddyfile.example caddy/Caddyfile

Edita el fichero .env y haz estos cambios:

  • DOMAIN : Este es tu dominio para acceder a Ghost.
  • ADMIN_DOMAIN : Si quieres, también puedes crear un acceso separado con un subdominio tipo admin.midominio.com en vez de entrar con /ghost. Esto es opcional, pero recomendado.
  • DATABASE_ROOT_PASSWORD : Genera una contraseña aleatoria con openssl rand -hex 32
  • DATABASE_PASSWORD : Genera una contraseña aleatoria con openssl rand -hex 32
  • SMTP Email section : Aquí debes de configurar el SMTP para tu Ghost. Puedes usar la misma configuración que ya tienes.

Configuración Caddy

Si has configurado ADMIN_DOMAIN, descomenta las lineas del final del fichero para activarlo.

{$ADMIN_DOMAIN} {
   import snippets/Logging

   # Traffic Analytics service
   import snippets/TrafficAnalytics

   # ActivityPub Service
   import snippets/ActivityPub

   # Default proxy everything else to Ghost
   handle {
          reverse_proxy ghost:2368
   }

Activar Social Web (ActivityPub)

Para activar la opción de conectarnos al Fediverso con ActivityPub, tendremos que editar el fichero .env y hacer las siguientes modificaciones:

Descomenta esta línea:

ACTIVITYPUB_TARGET=activitypub:8080

Edita y descomenta esta línea:

# COMPOSE_PROFILES=analytics,activitypub

En este tutorial sólo activaremos ActivityPub, para ello dejaremos la variable COMPOSE_PROFILES de la siguiente forma:

COMPOSE_PROFILES=activitypub

Migrar Ghost CLI a una instalación con Docker

Después de preparar todo el entorno para que funcione correctamente un script que tenemos que ejecutar para hacer el cambio, toca ejecutar el script.

📢
Antes de ejecutar el script de migración, asegúrate de tener un backup de todo, tanto ficheros como base de datos de Ghost.

Ejecuta el asistente de migración

Ten en cuenta que para que funcione correctamente, tendrás que detener Nginx si lo tienes activo en tu servidor, por lo que tienes otras webs en el servidor, deberás de tenerlo en cuenta.

bash scripts/migrate.sh

Al ejecutar el script, nos hará un resumen de lo que hará y si estamos de acuerdo:

WARNING: This script is currently in beta, please ensure you have a backup!

═══════════════════════════════════════════════════════════════════
                    GHOST MIGRATION SUMMARY
═══════════════════════════════════════════════════════════════════

This script will migrate your Ghost CLI installation to Docker.

WHAT WILL HAPPEN:
  ✓ Validate MySQL credentials
  ✓ Stop your current Ghost installation
  ✓ Copy content directory to Docker mount
  ✓ Export and import your database to a Docker based MySQL instance
  ✓ Start Ghost in Docker container
  ✓ Optionally configure Caddy Webserver for HTTPS

WHAT WONT HAPPEN:
  ✓ No data will be deleted
  ✓ Recovery script will be created
  ✓ Original installation remains intact

REQUIREMENTS:
  ✓ .env file configured for Docker
  ✓ MySQL credentials with dump permissions
  ✓ Sufficient disk space for migration

═══════════════════════════════════════════════════════════════════

Ready to proceed with migration? (y/n): y

Para responder correctamente al asistente de configuración es necesario tener a mano el usuario de la base de datos, el nombre de la base de datos y la contraseña.

Searching for Ghost installations in /var/www/...

Found 1 Ghost installation(s) in /var/www/:

  1) ghost (/var/www/ghost)
  2) Enter a different path

Select an installation (1-2): 1

Seleccionaremos la instalación de Ghost que nos ha detectado el asistente.

Checking disk space requirements...
  Content size: 348.51 KB
  Required space: 522.76 KB
  Available space: 21.34 GB
✓ Disk space check passed

Testing database export with Ghost's credentials...
✓ Ghost's credentials have sufficient privileges
✓ Recovery script created at: /opt/ghost/recovery_instructions.sh

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️  YOUR SITE WILL BE UNAVAILABLE DURING MIGRATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The next steps will:
  1. Stop your Ghost service
  2. Migrate your content and database
     a. Your new content directory will be at /opt/ghost/data/ghost/
     b. Your new MySQL database will be at /opt/ghost/data/mysql/
  3. Start Ghost in Docker

If anything goes wrong, run: bash /opt/ghost/recovery_instructions.sh

Continue with migration? This will make your site unavailable. (y/n): 

Tras indicarle la instalación, hará una serie de comprobaciones, tanto de espacio de disco, como probar las credenciales de la base de datos que hay en nuestro fichero de configuración. Finalmente te pregunta si quieres continuar con la migración.

Stopping Ghost service...
✓ Recovery script created at: /opt/ghost/recovery_instructions.sh
✓ Ghost service stopped
Starting MySQL container for migration...

[+] Running 10/12
 ⠼ db [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿] 228.8MB / 235.1MB Pulling          12.4s 
   ✔ 3d2798b2072a Pull complete                          4.1s 
   ✔ 314d9502df6c Pull complete                          4.2s 
   ✔ 79935e3fc39a Pull complete                          4.2s 
   ✔ 808046425533 Pull complete                          4.6s

Iniciará la migración de nuestro Ghost CLI, descargando los contenedores, copiando ficheros, importando la base de datos, etc. Esto puede tardar un poco.

Cuando acabe, nos preguntará si queremos iniciar el contenedor de Caddy:

Start Caddy Webserver for automatic HTTPS? This will stop Nginx. (y/n): 

En el caso de que no queramos configurar Caddy como servidor, podemos decirle que no y nos indicará que tendremos que crear un servidor web que apunte al puerto 2368 en localhost para cargar correctamente Ghost.

To finish migration, configure your webserver to forward traffic to 127.0.0.1:2368

Para hacer esto, tendremos que crear un Nginx Proxy:

Configurar Proxy Inverso con Nginx para que escuche a un puerto interno
En ocasiones tenemos servicios o aplicaciones web que escuchan directamente a un puerto interno. Para evitar acceder a dicha aplicación o servicio por la IP del servidor, una configuración que podemos hacer es acceder desde un Nginx Proxy.

Si no tenemos nada más en el servidor, podemos indicarle que configure Caddy en un contenedor:

Stopping Nginx...
Starting Caddy...
[+] Running 6/6
 ✔ caddy Pulled                        3.4s 
   ✔ f18232174bc9 Pull complete        0.7s 
   ✔ f5475df3da1b Pull complete        0.8s 
   ✔ 3b0ae3ace4a6 Pull complete        0.9s 
   ✔ eb621c62f244 Pull complete        1.7s 
   ✔ 4f4fb700ef54 Pull complete        1.7s 
[+] Running 5/5
 ✔ Volume "ghost_caddy_data"    Created   0.0s 
 ✔ Volume "ghost_caddy_config"  Created   0.0s 
 ✔ Container ghost-db-1         Healthy   0.6s 
 ✔ Container ghost-ghost-1      Running   0.0s 
 ✔ Container ghost-caddy-1      Started   0.9s 

✓ Caddy Webserver is running!
✓ Your site is available at: https://dominio.com

════════════════════════════════════════════════════════════
✓ MIGRATION COMPLETED SUCCESSFULLY!
════════════════════════════════════════════════════════════

Your Ghost site is now running in Docker!

Y con esto ya tendremos nuestro Ghost importado correctamente a Ghost Docker y funcionando con la última versión disponible:

# docker ps
CONTAINER ID  IMAGE               COMMAND                PORTS NAMES
51d3b7375c42  caddy:2.10.0-alpine "caddy run --config …" ...   ghost-caddy-1
32cd398276fd  ghost:6-alpine      "docker-entrypoint.s…" ...   ghost-ghost-1
f7fe731513b3  mysql:8.0.42        "docker-entrypoint.s…" ...   ghost-db-1

¿Algo ha ido mal?

Si durante el proceso tienes algún problema (yo he probado este procedimiento 5 veces y en ninguna he tenido problema) pero los de Ghost son conscientes de que algo puede ir mal y por eso han creado otro script que deja todo funcionando de nuevo:

bash recovery_instructions.sh

Más sobre ./voidNull

Haz que cada palabra cuente: tu donación nos inspira a seguir creando contenido. Accede al apartado de Donación para hacer tu aportación