Hace poco me propuse un reto personal para entrevistas tecnicas: reforzar mis habilidades en C# construyendo un microservicio con .NET 8. La idea era sencilla: un servicio capaz de subir imágenes y documentos PDF a un bucket de S3 y almacenarlos como parte de un flujo típico en muchas aplicaciones modernas.
Para hacerlo más completo, decidí levantar no solo el microservicio, sino también la infraestructura necesaria usando Docker y Docker Compose. Creé contenedores con SQL Server para manejar la base de datos, y para emular AWS S3 encontré una herramienta que me cambió el juego: LocalStack.

Descubriendo LocalStack
Lo que quería era simular AWS S3 de manera local, sin tener que depender de una cuenta en la nube ni generar costos. Investigando alternativas, encontré LocalStack, un proyecto que permite emular servicios de AWS en tu máquina local de forma sencilla.
Lo que más me llamó la atención fue:
- La posibilidad de simular servicios como S3, DynamoDB, SQS, Lambda y más.
- El hecho de que podía integrarlo sin fricción dentro de mis contenedores Docker.
- Que estaba diseñado para pruebas y desarrollo, justo lo que necesitaba para mi microservicio.
Con LocalStack, podía crear buckets, subir archivos y recuperar objetos como si estuviera usando AWS real, pero trabajando totalmente desde mi Mac Mini M4.
El reto de la persistencia en Mac
La primera vez que probé LocalStack me encontré con un problema que seguro le ha pasado a más de uno:
- Subía mis imágenes y PDFs desde el microservicio en C#.
- Todo funcionaba perfecto… hasta que reiniciaba el contenedor.
- De pronto, los objetos desaparecían como si nunca hubieran existido.
Naturalmente, busqué en la documentación y encontré la variable DATA_DIR
, que prometía habilitar persistencia. Configuré mi docker-compose.yml
para que guardara los datos en /tmp/localstack/data
.
Pero al reiniciar, apareció un error molesto:
rm: cannot remove '/tmp/localstack/data': Device or resource busy
ERROR: the LocalStack runtime exited unexpectedly
El contenedor no levantaba y me quedé bloqueado.
La solución: LS_DATA_DIR
Después de investigar y hacer varias pruebas, descubrí que el problema era que LocalStack intentaba limpiar /tmp/localstack
cada vez que iniciaba, y al tenerlo montado como volumen desde el host, entraba en conflicto.
La solución resultó ser muy simple: en lugar de usar DATA_DIR
, había que configurar LS_DATA_DIR
y montar un directorio diferente al de /tmp/localstack
.
Mi configuración final de docker-compose.yml
quedó así:
version: "3.9"
services:
localstack:
image: localstack/localstack:latest
platform: linux/arm64
container_name: localstack
ports:
- "4566:4566"
- "4571:4571"
environment:
- SERVICES=s3
- DEBUG=1
- LS_DATA_DIR=/var/lib/localstack/data
- AWS_ACCESS_KEY_ID=test
- AWS_SECRET_ACCESS_KEY=test
volumes:
- "./localstack-data:/var/lib/localstack/data"
networks:
- dev-network
networks:
dev-network:
driver: bridge
Con este cambio:
- LocalStack guarda los datos en
/var/lib/localstack/data
dentro del contenedor. - Ese directorio está montado en
./localstack-data
en mi máquina, asegurando persistencia real. - Reinicié varias veces, subí objetos, y ahí seguían intactos.
Si estás practicando con microservicios, cloud o arquitectura moderna, te recomiendo que pruebes LocalStack. Te permitirá avanzar mucho más rápido, ahorrar costos y ganar confianza antes de dar el salto a la nube real.
Si les sirvio no olviden compartir y comentar.
Saludos y happy coding 💻