DEV Community

De cero a la nube: cómo dockericé mi feed de AWS y lo desplegué en ECS

Hace unas semanas me cansé de entrar manualmente a la página de AWS What's New para ver qué habían lanzado. Así que hice lo que cualquier persona razonable haría: construí una app, la metí en Docker y la subí a ECS. En este artículo te cuento exactamente cómo, con todos los comandos y sin saltarme pasos.


¿Qué vamos a construir?

Una pequeña app web en Python (Flask) que consume el RSS público de AWS y muestra las últimas novedades clasificadas por categoría (AI/ML, Seguridad, Data, FinOps, CloudOps). Tiene modo oscuro y claro, animaciones de entrada y muestra hace cuánto tiempo se publicó cada novedad.

El flujo completo es:

Código local  →  Docker image  →  Amazon ECR  →  Amazon ECS (Fargate)  →  URL pública
Enter fullscreen mode Exit fullscreen mode

Repositorio: github.com/carotechie/docker-ecs-feedaws


Lo que necesitas antes de empezar

  • Docker Desktop instalado y corriendo
  • AWS CLI configurada (aws configure)
  • Una cuenta de AWS con permisos para ECR y ECS
  • Python 3.12+ (solo para desarrollo local)

1. La app: Flask + feedparser

El código principal es minimalista. app.py hace tres cosas: consume el RSS de AWS, limpia el HTML que viene en los summaries y detecta la categoría de cada novedad según sus palabras clave.

# app.py (fragmento)
AWS_RSS_URL = "https://aws.amazon.com/about-aws/whats-new/recent/feed/"

@app.route("/")
def index():
    feed = feedparser.parse(AWS_RSS_URL)
    # ...procesa y clasifica cada entrada
    return render_template("index.html", items=items, fetched_at=fetched_at)
Enter fullscreen mode Exit fullscreen mode

No hay base de datos, no hay caché. Cada vez que alguien entra a la URL, la app hace un request al RSS de AWS en ese instante. Simple y siempre actualizado.

Las dependencias van en requirements.txt:

flask==3.1.1
feedparser==6.0.11
gunicorn==23.0.0
Enter fullscreen mode Exit fullscreen mode

2. El Dockerfile

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]
Enter fullscreen mode Exit fullscreen mode

Nada del otro mundo. Usamos python:3.12-slim para mantener la imagen liviana y gunicorn como servidor WSGI (más robusto que el servidor de desarrollo de Flask para producción).

Un detalle importante: copiamos requirements.txt antes que el resto del código. Esto aprovecha el caché de capas de Docker — si no cambias las dependencias, Docker reutiliza esa capa y el build es mucho más rápido.


3. Probar localmente

# Construir la imagen
docker build -t mifeed-aws .

# Correr el contenedor
docker run -d -p 8080:8080 --name mifeed mifeed-aws

# Verificar que levantó
curl http://localhost:8080/health
# → {"status": "ok"}
Enter fullscreen mode Exit fullscreen mode

Abre http://localhost:8080 en tu navegador y deberías ver algo así:



Al entrar a http://localhost:8080



Para detenerlo:

docker stop mifeed && docker rm mifeed
Enter fullscreen mode Exit fullscreen mode

4. Subir la imagen a Amazon ECR

Amazon ECR (Elastic Container Registry) es el registro privado de imágenes Docker de AWS. Piénsalo como un Docker Hub pero dentro de tu cuenta de AWS.

4.1 Crear el repositorio en ECR

aws ecr create-repository \
  --repository-name demos/mifeed-aws \
  --region us-east-1
Enter fullscreen mode Exit fullscreen mode

El comando devuelve un JSON. Copia el valor de repositoryUri, lo vas a necesitar. Se ve así:

url.dkr.ecr.us-east-1.amazonaws.com/demos/mifeed-aws
Enter fullscreen mode Exit fullscreen mode

Mi repositorio en AWS ECR

4.2 Autenticarte con ECR

aws ecr get-login-password --region us-east-1 \
  | docker login \
    --username AWS \
    --password-stdin \
    url.dkr.ecr.us-east-1.amazonaws.com
Enter fullscreen mode Exit fullscreen mode

Si ves Login Succeeded, estás lista para el siguiente paso.

4.3 Etiquetar y subir la imagen

ECR_URI=url.dkr.ecr.us-east-1.amazonaws.com/demos/mifeed-aws

# Etiquetar la imagen local con el URI de ECR
docker tag mifeed-aws:latest $ECR_URI:latest

# Subir al registro
docker push $ECR_URI:latest
Enter fullscreen mode Exit fullscreen mode

El push puede tardar unos minutos la primera vez. Verás las capas subiendo una por una.



docker push en progreso


La imagen subida a AWS ECR


5. Configurar y desplegar en Amazon ECS

ECS (Elastic Container Service) es el servicio administrado de AWS para correr contenedores. Usaremos Fargate, que es el modo serverless: no tienes que gestionar servidores ni instancias EC2.

El flujo en ECS tiene tres piezas:

Task Definition  →  Cluster  →  Service
(qué correr)        (dónde)     (cuántas copias y cómo)
Enter fullscreen mode Exit fullscreen mode

5.1 Crear el Cluster

Ve a la consola de AWS → ECS → ClustersCreate Cluster.


Cluster de ECS


Configuración:

  • Cluster name: mifeed-aws
  • Infrastructure: AWS Fargate (serverless)
  • Deja el resto por defecto y haz clic en Create

5.2 Crear la Task Definition

La Task Definition le dice a ECS qué imagen correr, cuánta CPU/memoria usar y en qué puerto escucha.

Ve a Task DefinitionsCreate new task definition.


Creamos el Task Definition


Configuración:

  • Task definition family: mifeed-aws
  • Launch type: AWS Fargate
  • CPU: 0.25 vCPU
  • Memory: 0.5 GB
  • Container name: mifeed-aws
  • Image URI: url.dkr.ecr.us-east-1.amazonaws.com/demos/mifeed-aws:latest
  • Container port: 8080
  • Protocol: TCP


**Configuración del contenedor en la Task Definition**


Haz clic en Create.

5.3 Crear el Service

El Service mantiene corriendo el número de Tasks que definas y las reinicia si fallan.

En tu cluster mifeed-aws → pestaña ServicesCreate.


Creemos el servicio


Configuración:

  • Family: mifeed-aws
  • Service name: mifeed-service
  • Desired tasks: 1
  • Launch type: Fargate
  • VPC: la VPC por defecto está bien para empezar
  • Subnets: selecciona al menos 2 subnets públicas
  • Security group: crea uno nuevo (o usa uno existente) con la siguiente regla de entrada:
Tipo Puerto Origen
Custom TCP 8080 0.0.0.0/0
  • Public IP: Enabled ← importante, sin esto no tendrás IP pública


**Configuración de red del Service**


Haz clic en Create Service y espera unos minutos a que el Task pase a estado RUNNING.


Servicio en estado RUNNING


6. Conectarme a mi aplicación

Una vez que el Task está en RUNNING, la app ya está viva en internet.

Obtener la IP pública

En la consola: Clustersmifeed-awsTasks → clic en el Task ID → busca la sección Network → copia la Public IP.


IP pública del Task


Abre en tu navegador:

http://<PUBLIC_IP>:8080
Enter fullscreen mode Exit fullscreen mode

Y deberías ver tu feed funcionando en la nube:


La app en producción


Verificar el health check

curl http://<PUBLIC_IP>:8080/health
# → {"status": "ok"}
Enter fullscreen mode Exit fullscreen mode

¿Y las actualizaciones automáticas?

La app no necesita ninguna configuración especial. Como el feed se parsea en cada request, cada vez que alguien carga la página obtiene los datos más recientes de AWS. El contenedor puede estar corriendo semanas sin ningún reinicio y el feed siempre estará actualizado.

Si quieres que ECS descargue automáticamente una nueva versión de tu imagen cuando hagas cambios:

  1. Sube la nueva imagen a ECR con el mismo tag latest
  2. En ECS → tu Service → Update service → activa Force new deployment
  3. ECS descargará la nueva imagen y reemplazará el Task sin downtime

Reflexión final

Lo que me gustó de este ejercicio fue lo poco que tuve que tocar para pasar de "corre en mi máquina" a "corre en la nube":

  • El Dockerfile no cambió
  • La app no sabe si está en local o en ECS
  • La única diferencia real es de dónde viene la imagen (local vs ECR)

Eso es exactamente lo que hace valioso a Docker en un contexto de nube. El artefacto que pruebas localmente es el mismo artefacto que corre en producción.


Próximos pasos

Si quisieras llevar esto a producción real, los siguientes pasos serían:

  • Agregar un Load Balancer (ALB) para tener una URL fija en vez de una IP efímera
  • Dominio propio con Route 53 y un certificado SSL en ACM
  • CI/CD con GitHub Actions para que cada push a main actualice la imagen en ECR y fuerce un nuevo deploy en ECS
  • Auto Scaling para que el servicio escale según la carga

Top comments (0)