Cómo migrar un blog a Ghost >= 0.5 en Azure (node.js)

Informativo

En este artículo aprenderás a migrar tu blog Ghost hosteado en Azure a versión 0.5.7 o superior.

El procedimiento es muy fácil pero me enfocaré a que aprendas hacerlo tomando las medidas de seguridad necesarias para no complicarte la vida luego ;) y de paso como siempre enseñando algunos Ninja Tips.

Este artículo parte del hecho que ya tienes tu sitio Ghost andando en Azure.

Este artículo consta de las siguientes partes:

  1. Backup
  2. Creación de nuevo árbol de directorios
  3. Actualización de archivos de configuración
  4. Actualización local de paquetes de ghost
  5. Copia de datos a Azure

Backup

Como todo lo que se hace bien, hay que hacer copia de seguridad.

En Azure tienes muchas formas de hacerlo (git, ftp, backup automatizado etc), pero hoy trabajaremos todo este artículo con una super funcionalidad el service control manager : Kudu.

Supongamos que tu sitio está alojado en https://ghostjk.azurewebsites.net/ en este caso para acceder a Kudu vasta con agregar scm en la url así https://ghostjk.scm.azurewebsites.net/.

Ingresamos a esa URL, vamos a Debug Console > CMD y encontraremos algo como esto:

Consola de kudu

Buscamos desde allí al directorio de la web App que es /site/ lo podemos hacer por la consola con los comandos normales de esta, o por la interfaz web, da lo mismo.

Una vez estamos en /site ubicamos wwwroot en el costado izquierdo está el ícono de download el cual nos permite descargar la solución en un .zip.

Hecho, ese es nuestro backup.

Creación de nuevo árbol de directorios

Teniendo hecho nuestro backup procedemos a descomprimirlo en un directorio temporal.

Descargamos la versión de Ghost sobre la que queremos trabajar, esto podemos hacerlo de dos formas:

Esta la descomprimimos en el que será nuestro directorio de trabajo.

Desde nuestro backup copiaremos dentro de la carpeta content las siguientes sub-carpetas y todos sus contenidos

  • content/data
  • content/images
  • content/apps

De la siguiente carpeta debemos copiar todos nuestros temas instalados con excepción de casper el cual supongo tambien quieres actualizar a su ultima versión. Si le has realizado modificaciones ten presente hacer luego merge de los cambios.

  • content/themes

Actualización de archivos de configuración

En el directorio raiz creamos una copia del archivo config.example.js y la llamamos config.js, en el cual debes configurar con los datos de tu sitio para el ambiente de producción.

Recomendación

Otra alternativa es utilizar el config.js de tu backup pero no lo recomiendo pues a veces pueden venir cosas en la configuración que ya no son necesarias o son obsoletas. Sino sabes muy bien de que trata el archivo de configuración entonces simplemente copia el del backup.

Editamos el archivo config.js, allí ubicamos el árbol de producción y justo al final adicionamos el parámetro forceAdminSSL: false.

 production: {  
    url: 'https://ghostjk.azurewebsites.net/',
    mail: {
        transport: 'SMTP',
        options: {
            service: 'Mailgun',
            auth: {
                user: 'postmaster@xyxyxyxy.mailgun.org', // mailgun username
                pass: 'a1b2c3d4'  // mailgun password
            }
        }
    },
    database: {
        client: 'sqlite3',
        connection: {
            filename: path.join(__dirname, '/content/data/ghost.db')
        },
        debug: false
    },
    server: {
        // Host to be passed to node's `net.Server#listen()`
        host: '127.0.0.1',
        // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
        port: process.env.PORT
    }
    ,forceAdminSSL: false
},

forceAdminSSL Este parámetro en true fuerza a que el panel de administración de Ghost cargue por SSL, esta parámetro en las últimas versiones viene cargado por defecto en true. Esto es muy sano pero hay un problema: en la versión actual de iisnode de Azure esta configuración puede causar loops infinitos, por ello debemos deshablitarla, pero no se preocupen en la configuración de IIS podemos habilitarla de forma que no genere problemas.

En el directorio raiz creamos un archivo web.config opcionalmente puedes tomar el web.config existente en el backup y editarlo, aunque una vez más no lo recomiendo en la mayoria de casos.

En este archivo dejamos lo siguiente, hago enfasis en lo relacionado a suplir la funcionalidad de forceAdminSSL pero si vienes de una versión muy vieja de Ghost seguro la segunda parte tambien te genera curiosidad, esta última es la que ha reemplazado el uso de server.js que era necesario en las primeras versiones de Ghost sobre Azure.

 <?xml version="1.0" encoding="utf-8"?>  
<configuration>
  <system.webServer>
    <httpErrors existingResponse="PassThrough" />
    <handlers>
      <add name="iisnode" path="index.js" verb="*" modules="iisnode"/>
    </handlers>
    <rewrite>
      <rules>
        <rule name="ForceAdminSSL" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="(ghost.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="^OFF$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}"/>
        </rule>
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
          </conditions>
          <action type="Rewrite" url="index.js"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Actualización local de paquetes de ghost

Para poder hacer este paso ya deberias tener instalado node.js en tu máquina.

Desde la consola de comandos vas a la carpeta donde tienes tu nueva instalación de Ghost, y allí ejecutas

 npm install --production  

lo cual puede tardar un poco, una vez finalice:

 npm start  

Luego obtendrás algo como esto

 > ghost@0.5.7 start K:\GitRepos\bkrep\ghostjk-wrk
> node index

Migrations: Up to date at version 003

Warning: Found a theme with no package.json file  
 Theme name: gamma
 This will be required in future. Please see https://docs.ghost.org/themes/

Ghost is running in development...  
Listening on 127.0.0.1:2368  
Url configured as: https://my-ghost-blog.com  
Ctrl+C to shut down

Copia la url en el browser y todo debe funcionar, de acuerdo a la base de datos que tengas configurada en el config.js para tu ambiente de desarrollo. Es decir sino te fijaste puede arrancar un nuevo blog en blanco para tu ambiente de desarrollo.

Ctrl+C para detener el sitio.

Copia de datos a Azure

Es hora de subir nuestro sitio.

Desde el portal de Azure apagamos nuestro sitio, regresamos a Kudu y desde allí BORRAMOS las siguientes carpetas y archivos desde la consola de comandos o desde la UI web con el botón .

  • site/wwwroot/core
  • site/wwwroot/content/themes/casper
  • site/wwwroot/web.config
  • site/wwwroot/config.js
  • site/wwwroot/bower.json
  • site/wwwroot/package.json
  • site/wwwroot/Gruntfile.js
  • site/wwwroot/index.js

Nos aseguramos de quedar ubicados en site/wwwroot/ Ahora desde nuestra copia local hacemos drag & drop de los archivos de configuración hasta el website de Kudu.

  • web.config
  • config.js
  • bower.json
  • package.json
  • Gruntfile.sj
  • index.js

Kudu Drag And Drop

Regresamos a nuestra carpeta de trabajo local y con nuestra herramienta de preferencia comprimimos las siguientes carpetas creando un archivo .zip

  • sites/wwwroot/core -> core.zip
  • sites/wwwroot/content/themes/casper -> casper.zip

Hacemos Drag & Drop de core.zip a Kudu tal como lo muestro en la imagen, y luego en la carpeta themes hacemos lo mismo con casper.zip.

Copia de zips a Kudu

Resulta que Kudu recibe archivos .zip y los descomprime lo cual es muy conveniente sobre todo cuando tenemos montones de archivos (se te parece a un sitio web?) pues las transferencias por FTP suelen tardar una eternidad por pura ineficiencia del protocolo.

Si bien en Kudu podriamos haber subido la carpeta completa esto tambien se haría a la final uno a uno y tardaria el mismo tiempo que hacerlo por FTP. Por contraste mejor la comprimimos, subimos un solo archivo pequeño y Kudu lo recibe y lo descomprime por nosotros. :)

Ahora el paso final es instalar los paquetes de node en el servidor tal como lo hicimos localmente, para ellos en Kudu vamos a /site/wwwroot y desde la consola le damos npm install --production.

npm install desde Kudu

Volvemos a iniciar nuestro sitio de Azure, accedemos a la URL y nada pasa :(

Es posible que despues de un rato el sitio te arranque en blanco, acá nos enfrentamos a dos situaciones.

  1. Espera unos 15 seg y luego recarga la página, puede que simplemente no haya terminado la migración de la BD, así que depues de 15 segundos todo deberia estar OK. ESCENARIO MAS COMÚN
  2. Puede que haya problemas con los paquetes de node, sino te funciono el paso anterior has lo siguiente: ESCENARIO MENOS COMÚN PERO MÁS ADVERSO
    • Baja el sitio de Azure, en Kudu ve a /site/wwwroot/nodemodules
    • Desde la UI borra el directorio .bin
    • en la consola escribe rm * -f -r esto borrará todos esos directorios, se paciente
      una vez borrados verifica que todos esten borrados y ahora borra /site/wwwroot/nodemodules
    • Regresa a /site/wwwroot/ y ejecuta de nuevo npm install --production
    • Sube el sitio de Azure, ingresa a la URL 1 o 2 veces sino te carga a la primera

Con esto todo deberia quedar OK, sino pues escríbeme en los comentarios.