Desarrolla y prueba aplicaciones AWS Cloud usando LocalStack y Docker
En el desarrollo de aplicaciones moderno, probar las aplicaciones en la nube localmente antes de desplegarlas en un entorno de producción te ayuda a realizar lanzamientos más rápido y con mayor confianza. Este enfoque implica simular servicios de forma local, identificar y corregir problemas de manera temprana y realizar iteraciones rápidas sin incurrir en costos ni enfrentarte a las complejidades de un entorno de nube completo. Herramientas como LocalStack se han vuelto invaluables en este proceso, ya que facilitan la emulación de servicios de AWS y la contenedorización de aplicaciones para entornos de prueba coherentes y aislados.
En esta guía, aprenderás a:
- Usar Docker para iniciar un contenedor de LocalStack
- Conectarte a LocalStack desde una aplicación no contenedorizada
- Conectarte a LocalStack desde una aplicación contenedorizada
¿Qué es LocalStack?
LocalStack es un emulador de servicios en la nube que se ejecuta en un solo contenedor en tu computadora. Proporciona una forma potente, flexible y económica de probar y desarrollar aplicaciones basadas en AWS de forma local.
¿Por qué usar LocalStack?
Simular los servicios de AWS localmente te ayuda a probar cómo interactúa tu aplicación con servicios como S3, Lambda y DynamoDB sin necesidad de conectarte a la nube real de AWS. Puedes realizar iteraciones rápidas en tu desarrollo, evitando el costo y la complejidad de desplegar en la nube durante esta fase.
Al imitar el comportamiento de estos servicios de forma local, LocalStack propicia ciclos de retroalimentación más rápidos. Tu aplicación puede interactuar con APIs externas, pero todo se ejecuta localmente, eliminando la necesidad de lidiar con el aprovisionamiento en la nube o la latencia de red.
Esto facilita la validación de integraciones y la prueba de escenarios basados en la nube sin necesidad de configurar roles o políticas de IAM en un entorno real. Puedes simular arquitecturas de nube complejas localmente y enviar tus cambios a AWS solo cuando estés listo.
Uso de LocalStack con Docker
La imagen oficial de Docker para LocalStack proporciona una manera conveniente de ejecutar LocalStack en tu máquina de desarrollo. Es de uso gratuito y no requiere ninguna clave de API para ejecutarse. Incluso puedes usar la extensión de LocalStack para Docker para interactuar con LocalStack mediante una interfaz gráfica de usuario.
Requisitos previos
Se requieren los siguientes requisitos previos para seguir esta guía práctica:
- Docker Desktop
- Node.js
- Python y pip
- Conocimiento básico de Docker
Iniciar LocalStack
Inicia una demostración rápida de LocalStack siguiendo estos pasos:
Comienza clonando una aplicación de ejemplo. Abre la terminal y ejecuta el siguiente comando:
$ git clone https://github.com/dockersamples/todo-list-localstack-docker $ cd todo-list-localstack-dockerIniciar LocalStack
Ejecuta el siguiente comando para levantar LocalStack.
$ docker compose -f compose-native.yml up -dEste archivo Compose también incluye especificaciones para una base de datos MongoDB requerida. Puedes verificar que los servicios estén en funcionamiento visitando el panel de Docker Desktop.

Verifica que LocalStack esté en funcionamiento seleccionando el contenedor y revisando los registros (logs).

Crear un bucket de Amazon S3 local
Cuando creas un bucket de S3 local usando LocalStack, básicamente estás simulando la creación de un bucket de S3 en AWS. Esto te ayuda a probar y desarrollar aplicaciones que interactúan con S3 sin necesidad de tener una cuenta de AWS real.
Para crear un bucket de Amazon S3 local, instala la
awscli-localCLI en tu sistema. El comandoawslocales un envoltorio ligero sobre la interfaz de línea de comandos de AWS para usar con LocalStack. Te ayuda a realizar pruebas y desarrollo en un entorno simulado en tu máquina local sin necesidad de acceder a los servicios reales de AWS.$ pip install awscli-localCrea un nuevo bucket de S3 dentro del entorno de LocalStack con el siguiente comando:
$ awslocal s3 mb s3://mysamplebucketEl comando
s3 mb s3://mysamplebucketle indica a la CLI de AWS que cree un nuevo bucket de S3 (mb significamake bucket) llamadomysamplebucket.Puedes verificar si el bucket de S3 se ha creado seleccionando el contenedor de LocalStack en el panel de Docker Desktop y viendo los registros. Los registros indicarán que tu entorno de LocalStack está configurado correctamente y que ahora puedes usar
mysamplebucketpara almacenar y recuperar objetos.

Uso de LocalStack en el desarrollo
Una vez que te hayas familiarizado con LocalStack, es hora de verlo en acción. En esta demostración, utilizarás una aplicación de ejemplo con un frontend en React y un backend en Node.js. Esta pila de aplicaciones utiliza los siguientes componentes:
- React: Un frontend intuitivo para acceder a la aplicación de lista de tareas (todo-list)
- Node.js: Un backend responsable de manejar las solicitudes HTTP
- MongoDB: Una base de datos para almacenar todos los datos de la lista de tareas
- LocalStack: Emula el servicio Amazon S3 para almacenar y recuperar imágenes

Conectarse a LocalStack desde una aplicación no contenedorizada
Es hora de conectar tu aplicación a LocalStack. El archivo index.js, ubicado en el directorio backend/, sirve como el punto de entrada principal para la aplicación backend.
El código interactúa con el servicio S3 de LocalStack, al cual se accede a través del endpoint definido por la variable de entorno S3_ENDPOINT_URL, típicamente establecida en http://localhost:4566 para el desarrollo local.
El S3Client del SDK de AWS está configurado para usar este endpoint de LocalStack, junto con credenciales de prueba (AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY) que también se obtienen de las variables de entorno. Esta configuración permite que la aplicación realice operaciones en el servicio S3 simulado localmente como si estuviera interactuando con el S3 real de AWS, aportando flexibilidad al código para diferentes entornos.
El código utiliza multer y multer-s3 para manejar las subidas de archivos. Cuando un usuario sube una imagen a través de la ruta /upload, el archivo se almacena directamente en el bucket de S3 simulado por LocalStack. El nombre del bucket se recupera de la variable de entorno S3_BUCKET_NAME. A cada archivo subido se le asigna un nombre único agregando la marca de tiempo actual al nombre de archivo original. Luego, la ruta devuelve la URL del archivo subido dentro del servicio S3 local, haciéndolo accesible de la misma manera que si estuviera alojado en un bucket de S3 real de AWS.
Veámoslo en acción. Comienza iniciando el servicio backend de Node.js.
Cambia al directorio backend/
$ cd backend/Instala las dependencias requeridas:
$ npm installConfiguración de variables de entorno de AWS
El archivo
.envubicado en el directorio backend/ ya contiene credenciales de marcador de posición (placeholders) y valores de configuración que LocalStack utiliza para emular los servicios de AWS. Las variablesAWS_ACCESS_KEY_IDyAWS_SECRET_ACCESS_KEYson credenciales de marcador de posición, mientras queS3_BUCKET_NAMEyS3_ENDPOINT_URLson configuraciones. No se necesitan cambios, ya que estos valores ya están configurados correctamente para LocalStack.TipDado que estás ejecutando MongoDB en un contenedor Docker y la aplicación backend de Node se está ejecutando de forma nativa en tu host, asegúrate de que
MONGODB_URI=mongodb://localhost:27017/todosesté configurada en tu archivo.env.MONGODB_URI=mongodb://localhost:27017/todos AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test S3_BUCKET_NAME=mysamplebucket S3_ENDPOINT_URL=http://localhost:4566 AWS_REGION=us-east-1Aunque el SDK de AWS normalmente podría usar variables de entorno que comiencen con
AWS_, esta aplicación específica hace referencia directa a las siguientes variablesS3_*en el archivo index.js (dentro del directoriobackend/) para configurarS3Client.const s3 = new S3Client({ endpoint: process.env.S3_ENDPOINT_URL, // Utiliza el endpoint proporcionado o recurre a los valores predeterminados credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'default_access_key', // Valores predeterminados para el desarrollo secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'default_secret_key', }, });Inicia el servidor backend:
$ node index.jsVerás el mensaje de que el servicio backend se ha iniciado correctamente en el puerto 5000.
Iniciar el servicio frontend
Para iniciar el servicio frontend, abre una nueva terminal y sigue estos pasos:
Dirígete al directorio
frontend:$ cd frontendInstala las dependencias requeridas
$ npm installInicia el servicio frontend
$ npm run devPara este momento, deberías ver el siguiente mensaje:
VITE v5.4.2 ready in 110 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h + enter to show helpAhora puedes acceder a la aplicación a través de http://localhost:5173. Adelante, sube una imagen seleccionando un archivo de imagen y luego el botón Upload.

Puedes verificar que la imagen se haya subido al bucket de S3 revisando los registros del contenedor de LocalStack:

El código de estado
200significa que la operaciónputObject, que implica subir un objeto al bucket de S3, se ejecutó con éxito dentro del entorno de LocalStack. LocalStack registra esta entrada para proporcionar visibilidad de las operaciones que se realizan. Esto ayuda a depurar y confirmar que tu aplicación está interactuando correctamente con los servicios emulados de AWS.Dado que LocalStack está diseñado para simular servicios de AWS localmente, esta entrada de registro muestra que tu aplicación está funcionando como se espera al realizar operaciones en la nube en un entorno de sandbox local.
Conectarse a LocalStack desde una aplicación Node contenedorizada
Una vez que has aprendido a conectar una aplicación Node.js no contenedorizada a LocalStack, es hora de explorar los cambios necesarios para ejecutar toda la pila de aplicaciones en un entorno contenedorizado. Para lograr esto, crearás un archivo Compose especificando todos los servicios requeridos: frontend, backend, base de datos y LocalStack.
Examina el archivo Docker Compose.
El siguiente archivo Docker Compose define cuatro servicios:
backend,frontend,mongodbylocalstack. Los serviciosbackendyfrontendson tus aplicaciones Node.js, mientras quemongodbproporciona una base de datos ylocalstacksimula servicios de AWS como S3.El servicio
backenddepende de los servicioslocalstackymongodb, asegurando que estén en funcionamiento antes de que este se inicie. También utiliza un archivo .env para las variables de entorno. El servicio frontend depende del backend y establece la URL de la API. El serviciomongodbutiliza un volumen persistente para el almacenamiento de datos, ylocalstackestá configurado para ejecutar el servicio S3. Esta configuración te ayuda a desarrollar y probar tu aplicación localmente con servicios similares a los de AWS.services: backend: build: context: ./backend dockerfile: Dockerfile ports: - 5000:5000 depends_on: - localstack - mongodb env_file: - backend/.env frontend: build: context: ./frontend dockerfile: Dockerfile ports: - 5173:5173 depends_on: - backend environment: - REACT_APP_API_URL=http://backend:5000/api mongodb: image: mongo container_name: mongodb volumes: - mongodbdata:/data/db ports: - 27017:27017 localstack: image: localstack/localstack container_name: localstack ports: - 4566:4566 environment: - SERVICES=s3 - GATEWAY_LISTEN=0.0.0.0:4566 volumes: - ./localstack:/docker-entrypoint-initaws.d volumes: mongodbdata:Modifica el archivo
.envbajo el directoriobackend/para que los recursos se conecten usando los nombres de red internos.TipSegún el archivo Compose anterior, la aplicación se conectaría a LocalStack usando el nombre de host
localstack, mientras que MongoDB se conectaría usando el nombre de hostmongodb.MONGODB_URI=mongodb://mongodb:27017/todos AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test S3_BUCKET_NAME=mysamplebucket S3_ENDPOINT_URL=http://localstack:4566 AWS_REGION=us-east-1Detener los servicios en ejecución
Asegúrate de detener los servicios de Node frontend y backend del paso anterior presionando “Ctrl+C” en la terminal. También deberás detener los contenedores de LocalStack y MongoDB seleccionándolos en el panel de Docker Desktop y eligiendo el botón "Delete".
Inicia la pila de la aplicación ejecutando el siguiente comando en la raíz del directorio del proyecto clonado:
$ docker compose -f compose.yml up -d --buildDespués de unos momentos, la aplicación estará en funcionamiento.
Crear un bucket de S3 manualmente
El bucket de AWS S3 no se crea de antemano mediante el archivo Compose. Ejecuta el siguiente comando para crear un nuevo bucket dentro del entorno de LocalStack:
$ awslocal s3 mb s3://mysamplebucketEl comando crea un bucket de S3 llamado
mysamplebucket.Abre http://localhost:5173 para acceder a la aplicación completa de lista de tareas y comenzar a subir imágenes al bucket de Amazon S3.
TipPara optimizar el rendimiento y reducir los tiempos de subida durante el desarrollo, considera subir archivos de imagen más pequeños. Las imágenes más grandes pueden tardar más en procesarse y podrían afectar la capacidad de respuesta general de la aplicación.
Resumen
Esta guía te ha llevado a través de la configuración de un entorno de desarrollo local utilizando LocalStack y Docker. Has aprendido a probar aplicaciones basadas en AWS de forma local, reduciendo costos y aumentando la eficiencia de tu flujo de trabajo de desarrollo.