Pasar al contenido principal

Migrando un Drupal complejo a Upsun: Arquitectura, desafíos y aprendizajes

PaaS (Platform as a Service) ha transformado la forma en que desarrollamos y gestionamos aplicaciones en la última década. Gracias a ellas, es posible disponer de entornos escalables, fácilmente replicables y cada vez más eficientes.

Un actor clave en este campo es Upsun, la plataforma anteriormente conocida como Platform.sh. A partir de ahora, nos referiremos a ella por su nombre actual. Recientemente hemos trabajado con Upsun en proyectos de alojamiento gestionado, y su principal ventaja es clara: menos tiempo invertido en infraestructura significa más tiempo disponible para el código, la funcionalidad y la calidad.

Recientemente migramos a Upsun un proyecto complejo con más de 30 sitios por país, un tráfico importante e integraciones con un comercio electrónico, un CRM (Microsoft Dynamics) y otros servicios de traducción automática, valoración de productos, gestión de RGPD, etc. En este artículo, queremos compartir las consideraciones que tuvimos, los retos a los que nos enfrentamos y las lecciones aprendidas.

Arquitectura y dimensionamiento

Migrar a una PaaS implica elegir el plan que mejor se adapte al proyecto. En nuestro caso, el plan Enterprise nos ofrecía lo que necesitábamos: múltiples entornos (desarrollo, preproducción y producción), junto con otros adicionales para probar nuevas funcionalidades o correcciones. Con el cambio a Upsun, estos planes ahora se llaman Fixed (recursos estáticos según lo acordado en el contrato de servicio), mientras que los planes Flex permiten un escalado dinámico bajo demanda.

Upsun no es una PaaS al uso. En lugar de proporcionar una infraestructura estática, te permite configurar tu entorno a tu gusto, estableciendo los servicios que necesitas dentro de los recursos globales que has contratado inicialmente en el modo Fixed, o que has definido en el modo Flex. Esto hace de Upsun una plataforma orientada a usuarios con cierta experiencia. Toda la configuración tanto de los servicios en particular como de la plataforma en general se realiza modificando algunos archivos:

  • services.yaml: Con este archivo, podemos definir qué servicios tendremos en nuestros entornos, desde bases de datos hasta capas de caché. Un ejemplo sería este, donde definimos un servicio de base de datos, una capa de caché con Redis y un servidor Solr para indexar los contenidos del sitio y dar funcionalidad al buscador.

    db:
        type: mariadb:12.0
        disk: 1024
    cache:
        type: redis:7.2
    search:
        type: solr:9.6
        disk: 512
        configuration:
            cores:
                main_core:
                    conf_dir: !archive "solr/core"
            endpoints:
                solr:
                    core: main_core
  • routes.yaml: Responsable de las rutas de acceso de la aplicación, aquí podemos establecer nuestra URL base, redirecciones, URLs para otras aplicaciones de nuestro proyecto, etc. En este ejemplo, definimos la URL básica del proyecto basándonos en la URL de nuestro sitio configurada en el panel de Upsun. Como tuvimos que añadir más reglas a nuestro proyecto migrado, tuvimos que añadir este archivo, pero si tu proyecto solo utiliza la URL por defecto, no es necesario, ya que Upsun proporciona una configuración por defecto:

    routes:
        "https://{default}/":
        type: upstream
        upstream: myapp:http
  • .platform.app.yaml: Este es el archivo central para definir la versión de PHP, el nombre del sitio, las variables de entorno, las dependencias o los puntos de montaje.

    name: 'mi sitio'
    # El runtime que utiliza la aplicación.
    type: 'php:8.3'
    # Paquetes en el contenedor web
    dependencies:
        php:
            composer/composer: '^2.8.2'
        nodejs:
            n: "*"
    # Variables de entorno
    variables:
        env:
            N_PREFIX: /app/.global
    # Relaciones con los servicios definidos en services.yaml
    relationships:
        database: 'db:mysql'
        redis: 'cache:redis'
        solr: 'search:solr'
        
    # Los hooks nos permiten ejecutar diferentes scripts en la construcción, despliegue, etc.
    hooks:
        build: echo "mi hook de construcción"
        deploy: echo "Desplegando app"
    # Definir procesos cron
    crons: 
        drupal:
            spec: '*/5 * * * *'
            commands:
                start: 'cd web ; drush cron'
                
    # Permite configurar en profundidad las reglas del servidor web
    web: ...

Como se puede ver, Upsun permite una personalización significativa de la infraestructura. Como mencionamos antes, esto diferencia a Upsun de los proveedores de PaaS típicos y lo convierte en un servicio especialmente adecuado para profesionales con al menos algo de experiencia en arquitectura. Esta flexibilidad nos permite adaptar el servicio a las necesidades específicas del sitio.

Este enfoque (mantener las definiciones de la infraestructura en archivos dentro del repositorio) consolida el concepto de Infraestructura como Código (IaC), una práctica que reduce drásticamente la probabilidad de errores manuales y ofrece un control total sobre los entornos desde el propio repositorio.

Despliegues y orquestación

Upsun utiliza entornos aislados basados en LXC y namespaces, con su propio sistema de orquestación inspirado en los conceptos de Docker. Cada servicio (PHP, base de datos, Redis, etc.) se ejecuta en su propio contenedor, gestionado automáticamente por la plataforma.

Cada despliegue reconstruye completamente el entorno, asegurando que esté siempre limpio y consistente. Además, la plataforma ofrece hooks en diferentes etapas del proceso para tareas como la generación de artefactos, la importación de configuración o la limpieza de caché, todo configurable en el archivo .platform.app.yaml.

Una práctica común en las PaaS es vincular los despliegues a un repositorio de código, con diferentes entornos ligados a ramas específicas. A la hora de gestionar el código y los despliegues en Upsun, existen dos enfoques principales:

  • Repositorio único: Todo el proyecto reside en un único repositorio vinculado directamente a la infraestructura. El artefacto de construcción (build artifact) se genera durante el propio proceso de despliegue, utilizando los hooks disponibles en Upsun.

    Upsun single repository diagram
  • Repositorios separados: Este enfoque utiliza dos repositorios: uno independiente de Upsun para el desarrollo y un segundo vinculado a Upsun donde se suben los artefactos de construcción desde un pipeline de CI/CD.

    Separated repositories diagram

Aunque en Metadrop preferimos el segundo enfoque, ya que permite un control más exhaustivo sobre lo que se despliega en nuestros entornos (incluyendo pruebas funcionales, de regresión visual, etc.), no siempre es posible utilizar un segundo repositorio, o el objetivo puede ser mantener todo el proceso dentro de la plataforma Upsun. Ambos enfoques son perfectamente válidos.

En nuestro caso, integramos nuestra propia herramienta de construcción de artefactos en el flujo de trabajo de despliegue de Upsun, y la integración fue rápida y sencilla. Esto nos permitió mantener un proceso de Integración Continua/Despliegue Continuo (CI/CD) alineado con nuestras prácticas internas, sin comprometer la estabilidad del entorno.

Preparando la migración

Días antes del cambio, preparamos los entornos en Upsun:

  • Organización y cuentas: El servicio de soporte creó la organización, y nosotros gestionamos los usuarios y permisos desde el panel de control de Upsun, dando acceso a desarrolladores y administradores.
  • Repositorio: Aunque es posible utilizar el repositorio integrado de Upsun para el código base de nuestro sitio, optamos por seguir utilizando nuestro repositorio existente y activamos la integración de Upsun con esa fuente. Este enfoque nos permitió conservar nuestros sistemas de gestión de incidencias, CI y Wiki ya establecidos, y también evitó la necesidad de una migración completa del código y el historial.
  • Sincronización de la base de datos: La sincronización de la base de datos solo se realizará en ciertos entornos, como veremos más adelante. Generalmente, es suficiente con realizar un volcado (dump) del entorno antiguo e importarlo en Upsun. Esto se puede hacer normalmente conectándose al servidor por SSH o utilizando la herramienta CLI proporcionada por Upsun. Nota: Siempre se debe tener extremo cuidado con estos datos. Una vez importados, los volcados deben eliminarse inmediatamente.

    platform sql -p <PROJECT_ID> -e <ENVIRONMENT_NAME> < live_dump.sql
  • Sincronización de archivos estáticos: Esta tarea puede parecer sencilla a primera vista, ya que consiste principalmente en mover archivos de un servidor a otro. Sin embargo, cuando el volumen de información a mover es del orden de decenas de gigabytes, supone un reto importante. Esta fue una de las partes más problemáticas de nuestra migración. Más allá del gran volumen de datos, la complejidad añadida de esta tarea viene determinada en gran medida por la posibilidad de establecer una conexión directa desde el servidor original a Upsun para iniciar la sincronización. Si es posible una conexión directa entre servidores, bastará con una simple sincronización con `rsync`:

    # Ejemplo de comando rsync
    rsync -avz /misitio/web/sites/default/files/ usuario@servidor_upsun:/ruta/a/destino/web/sites/default/files/

    Si no es posible una conexión directa, será necesario sincronizar los datos a través de un tercer dispositivo o intentar iniciar `rsync` a través de un túnel SSH, garantizando siempre la seguridad de los datos.

    • Instalación inicial de los entornos: Una vez que el código base estuvo completamente integrado en la plataforma, todos los archivos estáticos y las bases de datos sincronizados, y los entornos activos, procedimos a preparar los scripts necesarios de generación de artefactos y despliegue para los distintos entornos. En esta ocasión, nos vimos obligados a utilizar el enfoque de repositorio único, lo que significa que la generación del artefacto se produjo como parte del propio proceso de despliegue. Con estos scripts, desplegamos los siguientes tres entornos de producción:
      • Dev: Despliegue rápido, con una instalación de Drupal desde la configuración, y contenido por defecto creado con el módulo default content.
      • Staging: Este es un entorno con una base de datos real de producción. Como tenemos una base de datos existente, no ejecutamos ninguna instalación de Drupal; en su lugar, ejecutamos los pasos habituales de despliegue de Drupal después de la construcción del artefacto: hacer una copia de seguridad de la base de datos y ejecutar "drush cache:rebuild", "drush updatedb", "drush config-import" y "drush cache:rebuild" de nuevo.
      • Live: Igual que staging, pero por primera vez, obtenemos una copia de seguridad de la infraestructura anterior.

Con todos los entornos completamente preparados, ejecutamos nuestra completa suite de pruebas. Esto normalmente cubre la mayor parte del sitio y todas las funcionalidades críticas, sirviendo como salvaguarda para mantener la estabilidad de nuestros sitios.

Además, una vez establecidos los entornos principales, el panel de control de Upsun nos permite configurar si cualquier nueva rama debe desencadenar la creación de un nuevo entorno, y de qué entorno padre debe heredar, en nuestro caso, 'develop'. También existe la opción de generar entornos únicamente al crear Merge/Pull requests.

Cuando un nuevo entorno hereda de otro, significa que, al desplegarse, recibirá una copia de la base de datos del entorno padre. Aunque no es estrictamente esencial para nuestro entorno 'develop', que se instala desde la configuración, esta característica resulta especialmente útil al generar entornos que heredan de 'staging' o 'production'.

Para minimizar las interrupciones, también redujimos el TTL del DNS, para que la propagación fuera lo más rápida posible cuando llegara el día de la migración.

Ejecutando la migración

El día de la transición es siempre crítico. Para asegurar el éxito, seguimos un procedimiento muy estructurado:

  1. Congelar los cambios en el antiguo entorno de producción para evitar inconsistencias: Para un sitio sencillo sin interacción de usuarios registrados, esto se puede lograr simplemente pidiendo a los editores que no accedan al sitio. En sitios más complejos, se puede hacer poniendo la base de datos en modo de solo lectura o utilizando módulos como Read-only mode.
  2. Copia de seguridad completa del sistema y sincronización: La base de datos debe ser importada de nuevo desde el servidor antiguo a Upsun, junto con los archivos estáticos (imágenes, CSS, etc.). Recuerda que la base de datos se puede sincronizar con la CLI de Upsun. Si los archivos estáticos se pueden sincronizar con `rsync`, bastará con una actualización acumulativa con `rsync`; si no, probablemente se requerirá una sincronización completa.
  3. Ejecutar todas las pruebas automatizadas y manuales: Una vez que todo está sincronizado, en nuestro caso, ejecutamos la suite de pruebas construida específicamente para cada proyecto. Esta suite suele cubrir la mayor parte del sitio y todas las funciones críticas, pero no elimina la necesidad de una verificación manual adicional antes de proceder al paso final.
  4. Cambio de DNS/CDN: una vez que confirmamos que todo funcionaba como se esperaba, el sitio está listo para ser publicado. En esta etapa, se deben actualizar los DNS para enviar todo el tráfico a los servidores de Upsun. También debemos tener en cuenta cualquier capa intermedia, como Fastly u otras CDN.

Gracias a esta secuencia, el tiempo de inactividad fue mínimo, y la migración fue percibida como prácticamente imperceptible para los usuarios finales.

Consideraciones si vas a migrar tus sitios a Upsun

Más allá de este caso específico, hay varios aspectos clave a tener en cuenta antes de dar el salto:

  • Dimensionamiento y presupuesto: Evalúa cuidadosamente el plan que necesitas y el coste asociado. Elegir entre Fixed o Flex puede marcar la diferencia en escalabilidad y optimización de recursos.
  • Estrategia de despliegue: Aunque puedes vincular directamente tu repositorio de desarrollo a Upsun, nuestra recomendación clave es que el repositorio conectado a la plataforma sea el artefacto ya compilado, utilizando, por ejemplo, drupal-artifact-builder dentro de un pipeline, usando la estrategia de "Repositorios separados" mencionada anteriormente. De esta manera, tienes un mejor control sobre qué y cuándo se despliega, manteniendo un repositorio separado para el desarrollo.
  • Servicios y versiones disponibles: Comprueba que Upsun ofrece todos los servicios que tu infraestructura necesita y en la versión correcta en su lista de servicios. Si no es así, no dudes en preguntar a su equipo si es posible añadirlos.
  • No es una PaaS típica: Si buscas una PaaS convencional donde todo está preconstruido y simplemente subes tus datos, entonces Upsun podría no ser la solución ideal para ti. Upsun ofrece una mayor flexibilidad, pero a costa de una mayor complejidad. En nuestro caso específico, consideramos que esto es una compensación positiva; sin embargo, el camino no siempre es sencillo. En ocasiones, a lo largo de estas migraciones, nos hemos encontrado con obstáculos desafiantes que requirieron un esfuerzo significativo para superarlos.

Conclusiones

Upsun es un PaaS que proporciona una mayor flexibilidad de infraestructura, lo que consecuentemente introduce un grado de complejidad durante la fase de preparación de la misma. Para nosotros, esto es una ventaja significativa, especialmente valiosa en proyectos más complejos donde la flexibilidad es crucial.

Finalmente, migrar tu proyecto a Upsun puede ser un proceso complejo. En Metadrop, somos partners oficiales de Upsun. Si tienes dudas o necesitas ayuda con la migración, no dudes en contactarnos.

Juanjo López photo

Juanjo López

Senior Drupal developer
Proyectos relacionados

DevOps / SysAdmin optimizado para Drupal

Ver más