En los últimos años, la adopción de arquitecturas serverless y el uso de servicios en la nube se ha convertido en la base para el desarrollo de aplicaciones modernas, especialmente en ámbitos como el Internet de las Cosas (IoT). Sin embargo, ciertas aplicaciones críticas y escenarios específicos requieren operar bajo condiciones que no permiten la dependencia del cloud, ya sea por requerimientos de offline total, seguridad, soberanía de datos o factores regulatorios. Este contexto ha impulsado a muchas organizaciones a migrar sus soluciones serverless originalmente diseñadas para la nube hacia infraestructuras on premise, un proceso que implica múltiples retos y aprendizajes. La complejidad de esta transición radica en preservar las funcionalidades, eficiencias y la experiencia adquirida en el entorno cloud, mientras se adaptan componentes esenciales para operar localmente. Migrar arquitecturas serverless a entornos on premise realmente significa rediseñar ciertos aspectos de la infraestructura, la orquestación, el manejo de datos, la autenticación y el monitoreo, sin perder de vista la escalabilidad y el rendimiento.
Un caso representativo es el de plataformas IoT que requieren procesar grandes volúmenes de datos en tiempo real provenientes de dispositivos distribuidos geográficamente. En la nube, estos sistemas se benefician de servicios gestionados como AWS Lambda, AWS IoT Core, Cognito, CloudWatch o bases de datos escalables como PostgreSQL con extensiones para geoposicionamiento. La migración a un entorno local obliga a encontrar equivalentes eficientes, muchas veces recorriendo soluciones open source robustas, pero que demandan un mayor esfuerzo de implementación y mantenimiento. La orquestación del ambiente se vuelve un punto central. En lugar de depender del aprovisionamiento automático de la nube, migrar el sistema on premise incluye la creación de infraestructura virtualizada que simplifique la gestión y actualizaciones.
Docker emerge como una opción preferida para contenerizar servicios, facilitando el despliegue consistente en servidores físicos locales. De este modo, se estructuran servidores dedicados, típicamente diferenciando un servidor de aplicación para manejar la lógica y procesamiento de mensajes, y otro servidor exclusivo para la base de datos, por ejemplo, PostgreSQL con PostGIS. Esta separación mejora el rendimiento, al evitar que las consultas intensas bloqueen los procesos de negocio. Otro componente crítico a adaptar es el broker de mensajes MQTT, fundamental para la comunicación eficiente entre dispositivos IoT y la plataforma. En la nube, los brokers pueden ser servicios gestionados con alta disponibilidad garantizada.
En local, la elección de brokers open source como Mosquitto resulta ideal por su ligereza y seguridad, ofreciendo controles de permisos y autenticación robustos para operar en redes internas. El manejo de la cola de mensajes también merece atención. RabbitMQ se presenta como una solución potente para administrar el flujo y garantizar alta disponibilidad y resiliencia del sistema. Sin embargo, para conectar diferentes protocolos como MQTT y AMQP, surge la necesidad de desarrollar un puente (bridge) que permita traducir y distribuir mensajes de manera correcta entre sistemas. Un gran desafío se encuentra en la migración de las funciones serverless Lambda, que en la nube actúan como procesamiento en tiempo real para mensajes y eventos.
Cuando se trasladan a un entorno local, estas funciones deben ser reprogramadas, con frecuencia en Node.js, para ejecutarse como aplicaciones que reciben eventos localmente y reemplazan llamadas remotas Lambda.invoke por invocaciones directas. El rendimiento, inicialmente limitado por la ejecución en modelo de un solo hilo y con una sola cola, requiere optimizaciones mediante procesamiento concurrente. Se implementa una arquitectura multi-hilo y multi-cola, donde gracias al manejo mediante el módulo cluster de Node.
js es posible crear un trabajador por núcleo de CPU, asignando a cada uno una cola especial. La distribución de mensajes se basa en el hashing del identificador del dispositivo, por ejemplo, su MAC address, asegurando que los mensajes para un mismo dispositivo se procesen secuencialmente y sin pérdida de orden. En el backend, la migración de Lambdas de API implica consolidar múltiples funciones en una aplicación monolítica basada en Express. Para minimizar reescrituras, se crea una capa intermedia que emula el formato de eventos típico de AWS, simplificando así la integración y preservando gran parte del código original. Automatizar la creación de rutas mediante archivos Swagger agiliza la generación y organización del código, garantizando consistencia y escalabilidad.
En cuanto a la autenticación, reemplazar servicios como AWS Cognito significa desarrollar un sistema de gestión basado en JSON Web Tokens (JWT), manteniendo la lógica de permisos y validaciones. Este enfoque permite gestionar de forma independiente y segura accesos y autorizaciones directamente desde la base de datos, reforzando así la soberanía sobre los datos y la infraestructura. En el frontend, mantener la experiencia de usuario implica conservar las aplicaciones React existentes, pero adaptando la distribución a servidores locales como Nginx, manejando manualmente certificados SSL para garantizar seguridad en las comunicaciones con HTTPS. Un aspecto esencial en la operación on premise es la implementación de un sistema robusto de monitoreo y logging. Sin el respaldo de servicios en la nube como CloudWatch, es necesario confiar en herramientas de código abierto para asegurar visibilidad y rápida detección de incidencias.
Logrotate ayuda en la gestión eficiente de registros, rotando y comprimiendo logs para evitar problemas de almacenamiento. Para el monitoreo en tiempo real y la generación de alertas, Prometheus y node_exporter proyectan métricas vitales de los recursos del servidor, como uso de CPU, memoria o disco. Configurar reglas de alerta personalizadas contribuye a una respuesta ágil ante cualquier anomalía, sosteniendo así la confiabilidad de la plataforma. Al concluir el proceso de migración, se observa que el principal beneficio es la independencia del entorno cloud, permitiendo operación totalmente offline sin colas ni demoras por arranques en frío. Esto es crucial para sistemas cuyo desempeño en tiempo real no puede ser comprometido.
No obstante, esta libertad tiene su precio: mayor responsabilidad en mantenimiento, seguridad, respaldo y actualización de hardware y software, tareas anteriormente absorbidas por el proveedor cloud. Finalmente, esta transición representa un balance importante entre conveniencia y autonomía. La migración exitosa abre la puerta a personalizaciones específicas, controles más férreos y una visión más profunda de las operaciones. Para clientes con requisitos estrictos de privacidad, disponibilidad o conectividad, las soluciones on premise bien diseñadas pueden ofrecer una base sólida, ágil y confiable para el desarrollo continuo y la expansión futura.