Cuando desarrollamos una aplicación web no tenemos por qué encargarnos de todos los componentes necesarios para que funcione. Podemos desarrollar y administrar nosotros mismos el servidor, el sistema operativo, el entorno de ejecución, la base de datos y la aplicación, o podemos delegar parte de estas tareas en proveedores cloud.
Desde el punto de vista de un desarrollador, la principal diferencia entre los distintos modelos de servicios cloud es qué parte de la infraestructura y del software gestionamos nosotros y qué parte proporciona el proveedor. En esta unidad estudiaremos las principales opciones y conceptos necesarios para comprender el ecosistema actual de despliegue en la nube, y practicaremos con un ejemplo en alguna de ellas.
Los servicios cloud pueden clasificarse atendiendo al nivel de responsabilidad que asume el proveedor frente al desarrollador. La clasificación tradicional distingue tres modelos principales:
Estos modelos representan diferentes niveles de abstracción y de responsabilidad entre el proveedor y el desarrollador. A continuación explicamos las características principales de cada uno.
IaaS o Infraestructura como Servicio consiste en contratar recursos informáticos como máquinas virtuales, almacenamiento, redes o capacidad de procesamiento. El proveedor se encarga de la infraestructura física, pero nosotros seguimos teniendo que administrar gran parte del entorno en el que se ejecutará nuestra aplicación.
Por ejemplo, podemos contratar una máquina virtual e instalar en ella Linux, Node.js, Express y nuestra aplicación. También tendremos que encargarnos de tareas como las actualizaciones, la configuración de la red, la seguridad y el mantenimiento del sistema. Proporciona, por tanto, mucho control, pero también mucha responsabilidad. Algunos ejemplos son Amazon EC2, Azure Virtual Machines o Google Compute Engine.
PaaS o Plataforma como Servicio proporciona un entorno preparado para ejecutar nuestras aplicaciones. El proveedor se encarga de gran parte de la infraestructura y nosotros nos centramos principalmente en desarrollar, configurar y desplegar nuestro software. Algunos ejemplos son Render, Railway, Google App Engine o Azure App Service.
Podemos conectar un repositorio de GitHub con una plataforma como Render y configurar los comandos necesarios para construir y ejecutar nuestro backend Node.js + Express. La plataforma se ocupa de gran parte de las tareas relacionadas con el servidor y nosotros nos centramos en nuestra aplicación. PaaS ofrece, por tanto, menos control que IaaS, pero simplifica considerablemente el despliegue y el mantenimiento.
SaaS o Software como Servicio es el nivel más alto de abstracción en la nube. Consiste en utilizar una aplicación completamente desarrollada, alojada y mantenida por un tercero, a la que solemos acceder a través de un navegador web o mediante una API.
En este modelo, el proveedor se encarga de todas las capas: infraestructura física, sistema operativo, base de datos, código de la aplicación y escalabilidad. Nosotros únicamente consumimos el servicio y gestionamos nuestra propia cuenta o datos.
Tradicionalmente está orientado a usuarios finales (como Google Workspace, Jira o GitHub) pero, desde la perspectiva de un desarrollador, este concepto se extiende a la integración de servicios especializados vía API o SDK. En lugar de construir subsistemas complejos desde cero, consumimos soluciones ya operativas para:
La principal ventaja es que podemos incorporar funcionalidades rápidamente sin tener que desarrollar y mantener toda la infraestructura necesaria. A cambio, nuestra aplicación pasa a depender del proveedor, de sus precios, límites, disponibilidad y API.
Con la evolución de la computación en la nube han aparecido otros modelos que describen formas específicas de consumir servicios cloud, como:
Estos conceptos no deben entenderse necesariamente como categorías independientes al mismo nivel que IaaS, PaaS y SaaS, sino como formas especializadas de ofrecer o consumir determinados servicios cloud.
También cabe mencionar que estos modelos no son necesariamente excluyentes. Una aplicación web moderna puede combinar diferentes servicios cloud. Por ejemplo, podemos desarrollar un frontend Angular y un backend Node.js + Express, y desplegarlos en una plataforma como Render, y utilizar MongoDB Atlas como servicio de base de datos. De esta forma, podemos construir una aplicación combinando software desarrollado por nosotros con infraestructura y servicios proporcionados por terceros.
Para mostrar un ejemplo de todo esto emplearemos Render. En los siguientes apartados probaremos a desplegar una API REST con Express y Mongoose, alojando la base de datos en MongoDB Atlas.
Como hemos comentado anteriormente, Render entra dentro de la categoría de PaaS (Platform as a Service), y nos proporciona un entorno completamente configurado para ejecutar nuestras aplicaciones web. Es especialmente interesante para nuestro caso porque permite desplegar actualmente servicios web Node.js/Express directamente desde un repositorio GitHub o similar, y dispone de una modalidad gratuita para experimentar (web oficial)
En Render podemos desplegar tanto servidores backend persistentes (desarrollados en Node.js, Python, Go o cualquier tecnología empaquetada con Docker), como sitios web frontend en HTML/CSS/JS servidos de forma rápida y gratuita a través de una red CDN. Además, permite alojar y gestionar bases de datos PostgreSQL y Redis, y también conectar con otras bases de datos remotas.
Como punto fuerte, permite mantener procesos en ejecución continua (como servidores Express o WebSockets) y ofrece redes privadas para conectar de forma segura nuestro backend con la base de datos sin exponerla a Internet. En su modalidad gratuita, los servicios web se suspenden tras unos 15 minutos sin tráfico, por lo que la primera petición tras la inactividad puede tardar unos segundos en responder (arranque en frío).
Si lo comparamos con un VPS (Servidor Privado Virtual), Render ofrece una serie de ventajas:
En cambio, en un VPS tenemos un control total del sistema y el entorno, pero debemos encargarnos de instalar y administrar todo: sistema operativo, servidores, conexiones remotas, etc.
Además, una de las características más potentes de las plataformas PaaS modernas es su integración directa con repositorios de GitHub o GitLab. Esto nos permite implementar un flujo de trabajo automatizado y continuo:
git push a la rama principal (main), el PaaS detecta automáticamente la nueva versión.npm install) y prepara los archivos para producción.npm run start o node server.js).Tomaremos como base el proyecto ContactosREST_v2 que se desarrolló en este documento. En él construimos una API REST para gestionar un modelo sencillo de contactos.
Aquí puedes descargar el código del proyecto que usaremos, desde un repositorio GitHub. Si le echas un vistazo, hay algunos pequeños cambios sobre el original de aquel documento:
.env.example con datos de prueba. Deberás copiarlo a otro llamado .env y cambiar en él los datos por los de tu propia conexión. Para gestionar las variables de entorno instalamos la librería dotenv desde package.json, junto con express y mongoose.PORT=3000
MONGODB_URI=mongodb+srv://usuario:password@url_cluster/nombreBD?parametros
node_modules como el fichero .env, que puede tener datos sensibles para pruebas en local (sólo se sube .env.example, con datos de prueba inofensivos).node_modules/
.env
También encontrarás un fichero db_seed.js en la raíz del proyecto, que contiene código para insertar en la base de datos una serie de contactos, restaurantes y mascotas de prueba, para que no esté vacía. Este fichero lo ejecutaremos luego para poblar la base de datos al inicio.
Adicionalmente, se han añadido unos scripts en la sección scripts de package.json para lanzar la aplicación con el comando npm (aunque también se puede lanzar con node index.js). Desde Render se podrá elegir el comando a ejecutar para ponerla en marcha.
"scripts": {
"start": "node index.js",
"dev": "node --watch index.js",
"seed": "node db_seed.js"
},
Como segundo paso importante deberemos tener una cuenta creada en MongoDB Atlas, y haber creado un cluster siguiendo los pasos indicados en este documento.
En el fichero .env de nuestro proyecto debemos tener almacenada la URL de conexión a la base de datos, con el formato ya conocido de mongodb+srv://usuario:password@url_cluster/nombreBD?parametros. Dentro de los parámetros, pueden venir bien un par de ellos:
mongodb+srv://usuario:password@url_cluster/nombreBD?retryWrites=true&w=majority
retryWrites=true permite que, si una operación de escritura (insert, update, delete) falla por un error temporal de red o una reorganización del clúster (por ejemplo, un cambio de nodo principal), el driver de Node.js la reintente automáticamente una vez antes de lanzar un error a tu aplicación. Evita que la API falle ante cortes momentáneos de conexión.w=majority establece el nivel de confirmación de escritura. En MongoDB Atlas los datos se replican en varios servidores (un conjunto de réplicas, usualmente 3 nodos). Con este parámetro indicamos a MongoDB que no devuelva la confirmación de éxito a la API hasta que el dato haya sido escrito físicamente en la mayoría de los nodos del clúster (al menos 2 de los 3). Garantiza que los datos no se pierdan si uno de los servidores sufre una caída justo después de recibir la petición.Ahora que ya tenemos configurado el proyecto Node de forma adecuada, y nuestro cluster en MongoDB Atlas, vamos a configurar un repositorio GitHub donde alojaremos nuestro proyecto, y a sincronizarlo con Render para que despliegue la aplicación.
Vamos a crear nuestro repositorio público en GitHub donde almacenar este proyecto. Supondremos, para este paso, que tienes cuenta creada en GitHub y que has instalado la herramienta Git en tu sistema. Si no es así, completa estos dos pasos antes de continuar.
Lo primero que haremos será inicializar un repositorio local en nuestra carpeta de proyecto Node. Podemos hacerlo desde el terminal integrado en VS Code, dentro del proyecto, escribiendo estos comandos:
# Inicializamos repositorio
git init
# Añadimos todo el contenido inicialmente (el fichero .gitignore excluye lo que corresponda)
git add .
git commit -m "Commit inicial: proyecto Express y Mongoose configurado"
# Renombramos la rama principal a "main" (opcional, aunque recomendable)
git branch -M main
Ahora debemos acceder a GitHub, crear un nuevo repositorio vacío (podemos llamarlo como queramos. Por ejemplo, ContactosREST) y quedarnos con su dirección (por ejemplo, https://github.com/tu_usuario/ContactosREST.git). Ahora vamos a conectar nuestro repositorio local con ese repositorio GitHub:
git remote add origin https://github.com/tu-usuario/tu-repositorio.git
git push -u origin main
Como último paso, vamos a crear un nuevo proyecto en nuestra cuenta de Render (si no la tienes, créala). Desde nuestro panel (Dashboard) elegimos crear un nuevo Web Service.
Después conectamos con el repositorio en cuestión
El siguiente paso es configurar el servicio. En el formulario nos piden que pongamos un nombre, el lenguaje o framework de desarrollo (Node), la rama principal del repositorio, la región donde desplegarlo…
También indicamos el comando para construir el proyecto (en nuestro caso, npm install) y para ponerlo en marcha (podemos elegir node index.js o bien npm run start de nuestros scripts). Finalmente, podemos especificar la tarifa (gratuita en nuestro caso) y las variables de entorno que se van a utilizar. Podemos añadirlas a mano o bien copiarlas/pegarlas de nuestro fichero .env (recuerda que este fichero NO se sube a GitHub).
En la sección de opciones avanzadas podemos especificar algún detalle más. Por ejemplo (para opciones de pago) podemos indicar un pre-deploy Command, que vendría bien para ejecutar npm run seed y poblar la base de datos al inicio. Como está deshabilitado para la opción gratuita, deberemos ejecutar este comando desde nuestro ordenador local para rellenar la base de datos de MongoDB Atlas.
Una vez rellenadas las opciones de configuración, podemos desplegar el servicio y, si todo es correcto, tras unos segundos para hacer el build e instalar las librerías necesarias, lo tendremos disponible en una dirección por defecto dentro del dominio xxxxx.onrender.com, donde xxxxx será el nombre que le hayamos dado al proyecto en Render.
Actualmente existen muchas plataformas PaaS y, aunque todas nos permiten conectar un repositorio de GitHub para automatizar el despliegue, cada una está pensada para resolver necesidades distintas, desde frontends estáticos optimizados en CDN hasta backends persistentes y bases de datos gestionadas. A continuación nombramos algunas con sus particulares características.
Aquí vemos un análisis comparativo de las plataformas comentadas: