<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carolina Herrera</title>
    <description>The latest articles on DEV Community by Carolina Herrera (@carotechie).</description>
    <link>https://dev.to/carotechie</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3671354%2F0251a11a-d5cc-41d9-8a6b-b4e67974e4d7.png</url>
      <title>DEV Community: Carolina Herrera</title>
      <link>https://dev.to/carotechie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carotechie"/>
    <language>en</language>
    <item>
      <title>I run infrastructure for the airline industry. Then I deployed a Flappy Bird clone with the same rigor.</title>
      <dc:creator>Carolina Herrera</dc:creator>
      <pubDate>Tue, 18 Aug 2026 11:51:21 +0000</pubDate>
      <link>https://dev.to/aws-builders/i-run-infrastructure-for-the-airline-industry-then-i-deployed-a-flappy-bird-clone-with-the-same-knh</link>
      <guid>https://dev.to/aws-builders/i-run-infrastructure-for-the-airline-industry-then-i-deployed-a-flappy-bird-clone-with-the-same-knh</guid>
      <description>&lt;p&gt;At work, downtime is not a ticket. It is a flight that does not take off. I have been leading DevOps teams in the airline industry since 2022, and that context shapes how I think about every deployment I touch.&lt;/p&gt;

&lt;p&gt;So one weekend I built a game based on one I liked so much: Flappy Bird, but this game is Flappy Docker where a Docker whale dodges containers instead of pipes, and then I did the thing that probably sounds ridiculous: I deployed it to ECS with Terraform, a real domain, HTTPS and autoscaling.&lt;/p&gt;

&lt;p&gt;It is a game nobody asked for. It is also the cheapest place I know to practice the whole path, image to registry to orchestrator to DNS, on something where breaking it costs me nothing.&lt;/p&gt;

&lt;p&gt;Play it: &lt;a href="https://flappy-docker.carolinaherreramonteza.com" rel="noopener noreferrer"&gt;https://flappy-docker.carolinaherreramonteza.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/carotechie/game-flappy-docker" rel="noopener noreferrer"&gt;https://github.com/carotechie/game-flappy-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feaypl97dcbizwngna043.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feaypl97dcbizwngna043.png" alt="How it looks Flappy Docker" width="530" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The game
&lt;/h2&gt;

&lt;p&gt;I kept the game deliberately boring. Vanilla HTML5 Canvas and JavaScript, no framework, no build step, because the game was never the interesting part.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index.html and style.css for layout and styling&lt;/li&gt;
&lt;li&gt;game.js for the game loop, collision detection, scoring and the difficulty ramp (speed goes up every 5 points)&lt;/li&gt;
&lt;li&gt;Best score saved in localStorage&lt;/li&gt;
&lt;li&gt;Controls: click, spacebar, arrow up, Enter, or tap on mobile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing ships in a four-line Dockerfile. nginx:alpine serving static files, nothing else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Locally that is three commands and you are playing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t flappy-docker .
docker run -d -p 8080:80 --name flappy-docker flappy-docker
open http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No npm install, no runtime version to match, no "works on my machine". That is the part I actually want people to take away from Docker, and it turns out a game makes them care enough to run the commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking it to AWS
&lt;/h2&gt;

&lt;p&gt;Once it worked locally I wanted it on a real domain. I also wanted to answer a question I keep getting, from people on my team and from people in the community: what does it really cost to run one small container on ECS?&lt;/p&gt;

&lt;p&gt;So I built it twice. Both profiles live in the same Terraform and you switch between them with a single variable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75sm64znkvgx3f1a9maz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F75sm64znkvgx3f1a9maz.png" alt="Architecture comparison: Full vs Low Cost" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;full&lt;/code&gt;, around $30 a month&lt;br&gt;
ECR, ECS, ALB, ACM and autoscaling. One to three tasks with CPU target tracking, HTTPS with a free ACM certificate, and an ALB health checking the tasks and replacing them when they die.&lt;/p&gt;

&lt;p&gt;This is what I would ship at work. The load balancer is most of the bill, and it is also most of the value: it gives you something stable to point DNS at, and it recovers on its own.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;low_cost&lt;/code&gt;, around $9 a month&lt;br&gt;
ECR, ECS and Route 53. One task, fixed. HTTP only. No load balancer.&lt;/p&gt;

&lt;p&gt;That last part creates a real problem. Without an ALB there is nothing stable to point DNS at, so a small helper script resolves the running task's public IP at terraform apply time and writes an A record with a low TTL.&lt;/p&gt;

&lt;p&gt;I want to be blunt about what that costs, because posts that show you the cheap option tend to skip this part. If the task restarts between applies, that record points at an IP that no longer exists. It stays wrong until the next apply. Nothing is watching and nothing heals itself.&lt;/p&gt;

&lt;p&gt;For a game on my personal domain I can live with that. For anything with people waiting on the other end, I would not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Terraform
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform/
├── components/          # reusable modules
│   ├── network/           # default VPC/subnets lookup
│   ├── ecr/                # image repository
│   ├── dns/                 # existing Route53 hosted zone lookup
│   ├── acm/                  # free TLS cert, DNS-validated, full mode only
│   ├── alb/                   # load balancer + listeners + DNS alias, full mode only
│   ├── ecs/                    # cluster, task definition, service
│   ├── autoscaling/             # target-tracking policy, full mode only
│   └── dns_task_record/          # IP-synced DNS record, low_cost mode only
├── vars/
│   ├── prod.tfvars                # deployment_mode = "full"
│   ├── prod-lowcost.tfvars        # deployment_mode = "low_cost"
│   ├── dev.tfvars
│   └── backend-*.hcl              # per-environment S3 backend config
├── main.tf / variables.tf / outputs.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;deployment_mode&lt;/code&gt; variable decides which modules exist. The ACM, ALB and autoscaling modules carry count = local.full_mode ? 1 : 0, so choosing a profile is just choosing a &lt;code&gt;.tfvars&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;State lives in S3 with Terraform 1.10 native locking (use_lockfile = true), which finally means no DynamoDB table sitting there just to hold a lock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd terraform
terraform init -backend-config=vars/backend-prod.hcl
terraform apply -target=module.ecr -var-file=vars/prod.tfvars   # create the repo first

REPO_URL=$(terraform output -raw ecr_repository_url)
docker build -t "$REPO_URL:latest" ..
docker push "$REPO_URL:latest"

terraform apply -var-file=vars/prod.tfvars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ECR repository has to exist before you can push an image to it, which is why that first apply is targeted. It is the kind of ordering detail that is obvious in hindsight and annoying the first time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2zry50xa834c6rmqzdch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2zry50xa834c6rmqzdch.png" alt="Terraform Apply 1" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7z8phbon0oombf9shvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7z8phbon0oombf9shvh.png" alt="Terraform Apply 2" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that the service comes up and the tasks register behind the target group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0wwgcgy6327tsnkzt8qd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0wwgcgy6327tsnkzt8qd.png" alt="ECS Tasks" width="799" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9h2zscyquaq7lf3sjeh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo9h2zscyquaq7lf3sjeh.png" alt="Target Group" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the game runs on its own subdomain over HTTPS, on a certificate that costs nothing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu8svrvrpe7r08n5xwtl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu8svrvrpe7r08n5xwtl8.png" alt="Route 53 setup" width="744" height="970"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would do differently
&lt;/h2&gt;

&lt;p&gt;If I ever needed low_cost mode to stay up without me watching it, I would replace my script with Cloud Map public DNS namespaces. That is the native AWS answer to this problem. It also brings Route 53 delegation complexity that I did not want to take on for a weekend project.&lt;/p&gt;

&lt;p&gt;CI/CD is the obvious next step: build, push, and ecs update-service --force-new-deployment on every push to main. Right now I do it by hand, which is fine until it is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bother with any of this
&lt;/h2&gt;

&lt;p&gt;The honest reason is that a side project is the only place where an expensive mistake is free. I cannot try out a routing decision on a system where a bad afternoon means people stuck at a gate. I can try it here, get it wrong, and fix it on a Sunday.&lt;/p&gt;

&lt;p&gt;If you are learning ECS or Terraform, my advice is to pick something you actually want to see running. It beats another tutorial you will abandon halfway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Live: &lt;a href="https://flappy-docker.carolinaherreramonteza.com" rel="noopener noreferrer"&gt;https://flappy-docker.carolinaherreramonteza.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/carotechie/game-flappy-docker" rel="noopener noreferrer"&gt;https://github.com/carotechie/game-flappy-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full deployment walkthrough for both modes: docs/SetupOnAWS.md, and in Spanish at docs/SetupOnAWS.es.md.&lt;/p&gt;

&lt;p&gt;If you dodge more than 10 containers, you are doing better than me.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>De cero a la nube: cómo dockericé mi feed de AWS y lo desplegué en ECS</title>
      <dc:creator>Carolina Herrera</dc:creator>
      <pubDate>Fri, 19 Jun 2026 02:08:33 +0000</pubDate>
      <link>https://dev.to/aws-builders/de-cero-a-la-nube-como-dockerice-mi-feed-de-aws-y-lo-desplegue-en-ecs-24f1</link>
      <guid>https://dev.to/aws-builders/de-cero-a-la-nube-como-dockerice-mi-feed-de-aws-y-lo-desplegue-en-ecs-24f1</guid>
      <description>&lt;p&gt;Hace unas semanas me cansé de entrar manualmente a la página de &lt;em&gt;AWS What's New&lt;/em&gt; 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Qué vamos a construir?
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;El flujo completo es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Código local  →  Docker image  →  Amazon ECR  →  Amazon ECS (Fargate)  →  URL pública
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Repositorio:&lt;/strong&gt; &lt;a href="https://github.com/carotechie/docker-ecs-feedaws" rel="noopener noreferrer"&gt;github.com/carotechie/docker-ecs-feedaws&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lo que necesitas antes de empezar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker Desktop instalado y corriendo&lt;/li&gt;
&lt;li&gt;AWS CLI configurada (&lt;code&gt;aws configure&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Una cuenta de AWS con permisos para ECR y ECS&lt;/li&gt;
&lt;li&gt;Python 3.12+ (solo para desarrollo local)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. La app: Flask + feedparser
&lt;/h2&gt;

&lt;p&gt;El código principal es minimalista. &lt;code&gt;app.py&lt;/code&gt; 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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app.py (fragmento)
&lt;/span&gt;&lt;span class="n"&gt;AWS_RSS_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://aws.amazon.com/about-aws/whats-new/recent/feed/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feedparser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AWS_RSS_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...procesa y clasifica cada entrada
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fetched_at&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fetched_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Las dependencias van en &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;flask&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=3.1.1&lt;/span&gt;
&lt;span class="py"&gt;feedparser&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=6.0.11&lt;/span&gt;
&lt;span class="py"&gt;gunicorn&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=23.0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. El Dockerfile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.12-slim&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Un detalle importante: copiamos &lt;code&gt;requirements.txt&lt;/code&gt; &lt;strong&gt;antes&lt;/strong&gt; 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Probar localmente
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Construir la imagen&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; mifeed-aws &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Correr el contenedor&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;--name&lt;/span&gt; mifeed mifeed-aws

&lt;span class="c"&gt;# Verificar que levantó&lt;/span&gt;
curl http://localhost:8080/health
&lt;span class="c"&gt;# → {"status": "ok"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abre &lt;code&gt;http://localhost:8080&lt;/code&gt; en tu navegador y deberías ver algo así:&lt;/p&gt;







&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkxvop0bduk6j2nigjnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkxvop0bduk6j2nigjnx.png" alt="Al entrar a http://localhost:8080" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;







&lt;p&gt;Para detenerlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop mifeed &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker &lt;span class="nb"&gt;rm &lt;/span&gt;mifeed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Subir la imagen a Amazon ECR
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Crear el repositorio en ECR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr create-repository &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repository-name&lt;/span&gt; demos/mifeed-aws &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El comando devuelve un JSON. Copia el valor de &lt;code&gt;repositoryUri&lt;/code&gt;, lo vas a necesitar. Se ve así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;url.dkr.ecr.us-east-1.amazonaws.com/demos/mifeed-aws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbhs4nwpqo56ea8cjescl.png" alt="Mi repositorio en AWS ECR" width="800" height="206"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.2 Autenticarte con ECR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  | docker login &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    url.dkr.ecr.us-east-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si ves &lt;code&gt;Login Succeeded&lt;/code&gt;, estás lista para el siguiente paso.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Etiquetar y subir la imagen
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;ECR_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;url.dkr.ecr.us-east-1.amazonaws.com/demos/mifeed-aws

&lt;span class="c"&gt;# Etiquetar la imagen local con el URI de ECR&lt;/span&gt;
docker tag mifeed-aws:latest &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest

&lt;span class="c"&gt;# Subir al registro&lt;/span&gt;
docker push &lt;span class="nv"&gt;$ECR_URI&lt;/span&gt;:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El push puede tardar unos minutos la primera vez. Verás las capas subiendo una por una.&lt;/p&gt;







&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi6v0kv6aayv340zmz60z.png" alt="docker push en progreso" width="800" height="339"&gt;
&lt;/h2&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkd5tvmhsyzrafb676z4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkd5tvmhsyzrafb676z4h.png" alt="La imagen subida a AWS ECR" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Configurar y desplegar en Amazon ECS
&lt;/h2&gt;

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

&lt;p&gt;El flujo en ECS tiene tres piezas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task Definition  →  Cluster  →  Service
(qué correr)        (dónde)     (cuántas copias y cómo)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.1 Crear el Cluster
&lt;/h3&gt;

&lt;p&gt;Ve a la consola de AWS → ECS → &lt;strong&gt;Clusters&lt;/strong&gt; → &lt;strong&gt;Create Cluster&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgm07i0gchads0xxb2hz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgm07i0gchads0xxb2hz8.png" alt="Cluster de ECS" width="800" height="724"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Configuración:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cluster name:&lt;/strong&gt; &lt;code&gt;mifeed-aws&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; AWS Fargate (serverless)&lt;/li&gt;
&lt;li&gt;Deja el resto por defecto y haz clic en &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2 Crear la Task Definition
&lt;/h3&gt;

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

&lt;p&gt;Ve a &lt;strong&gt;Task Definitions&lt;/strong&gt; → &lt;strong&gt;Create new task definition&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj7dr9jmeq3bphlhmzpql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj7dr9jmeq3bphlhmzpql.png" alt="Creamos el Task Definition" width="800" height="878"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Configuración:&lt;/p&gt;

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







&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc8tq45cblaw3bdebqwu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc8tq45cblaw3bdebqwu.png" alt="**Configuración del contenedor en la Task Definition**" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Haz clic en &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3 Crear el Service
&lt;/h3&gt;

&lt;p&gt;El Service mantiene corriendo el número de Tasks que definas y las reinicia si fallan.&lt;/p&gt;

&lt;p&gt;En tu cluster &lt;code&gt;mifeed-aws&lt;/code&gt; → pestaña &lt;strong&gt;Services&lt;/strong&gt; → &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlbsiit51c36ljo2zwv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzlbsiit51c36ljo2zwv5.png" alt="Creemos el servicio" width="800" height="657"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Configuración:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Family:&lt;/strong&gt; &lt;code&gt;mifeed-aws&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service name:&lt;/strong&gt; &lt;code&gt;mifeed-service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desired tasks:&lt;/strong&gt; &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Launch type:&lt;/strong&gt; Fargate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC:&lt;/strong&gt; la VPC por defecto está bien para empezar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnets:&lt;/strong&gt; selecciona al menos 2 subnets públicas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security group:&lt;/strong&gt; crea uno nuevo (o usa uno existente) con la siguiente regla de entrada:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Puerto&lt;/th&gt;
&lt;th&gt;Origen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Custom TCP&lt;/td&gt;
&lt;td&gt;8080&lt;/td&gt;
&lt;td&gt;0.0.0.0/0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public IP:&lt;/strong&gt; Enabled ← &lt;strong&gt;importante&lt;/strong&gt;, sin esto no tendrás IP pública&lt;/li&gt;
&lt;/ul&gt;







&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuphwr7n5a78y9jm3bjks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuphwr7n5a78y9jm3bjks.png" alt="**Configuración de red del Service**" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Haz clic en &lt;strong&gt;Create Service&lt;/strong&gt; y espera unos minutos a que el Task pase a estado &lt;strong&gt;RUNNING&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgaogouebxxmx9xu7dzsc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgaogouebxxmx9xu7dzsc.png" alt="Servicio en estado RUNNING" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Conectarme a mi aplicación
&lt;/h2&gt;

&lt;p&gt;Una vez que el Task está en RUNNING, la app ya está viva en internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtener la IP pública
&lt;/h3&gt;

&lt;p&gt;En la consola: &lt;strong&gt;Clusters&lt;/strong&gt; → &lt;code&gt;mifeed-aws&lt;/code&gt; → &lt;strong&gt;Tasks&lt;/strong&gt; → clic en el Task ID → busca la sección &lt;strong&gt;Network&lt;/strong&gt; → copia la &lt;strong&gt;Public IP&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft3gza3ulzf63wx5kp3a2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft3gza3ulzf63wx5kp3a2.png" alt="IP pública del Task" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Abre en tu navegador:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;PUBLIC_IP&amp;gt;:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y deberías ver tu feed funcionando en la nube:&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts2a68ltjaajw953v1m1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts2a68ltjaajw953v1m1.png" alt="La app en producción" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Verificar el health check
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://&amp;lt;PUBLIC_IP&amp;gt;:8080/health
&lt;span class="c"&gt;# → {"status": "ok"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ¿Y las actualizaciones automáticas?
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Si quieres que ECS descargue automáticamente una nueva versión de tu imagen cuando hagas cambios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sube la nueva imagen a ECR con el mismo tag &lt;code&gt;latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;En ECS → tu Service → &lt;strong&gt;Update service&lt;/strong&gt; → activa &lt;strong&gt;Force new deployment&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;ECS descargará la nueva imagen y reemplazará el Task sin downtime&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Reflexión final
&lt;/h2&gt;

&lt;p&gt;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":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El &lt;code&gt;Dockerfile&lt;/code&gt; no cambió&lt;/li&gt;
&lt;li&gt;La app no sabe si está en local o en ECS&lt;/li&gt;
&lt;li&gt;La única diferencia real es de dónde viene la imagen (local vs ECR)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;h2&gt;
  
  
  Próximos pasos
&lt;/h2&gt;

&lt;p&gt;Si quisieras llevar esto a producción real, los siguientes pasos serían:&lt;/p&gt;

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

</description>
      <category>docker</category>
      <category>aws</category>
      <category>ecs</category>
      <category>containerapps</category>
    </item>
    <item>
      <title>Mi experiencia en el AWS re:Invent 2024: De Asistente a Speaker 🚀</title>
      <dc:creator>Carolina Herrera</dc:creator>
      <pubDate>Sun, 17 May 2026 13:56:30 +0000</pubDate>
      <link>https://dev.to/carotechie/mi-experiencia-en-el-aws-reinvent-2024-de-asistente-a-speaker-po0</link>
      <guid>https://dev.to/carotechie/mi-experiencia-en-el-aws-reinvent-2024-de-asistente-a-speaker-po0</guid>
      <description>&lt;p&gt;¡Hola a toda la comunidad de dev.to! 👋 &lt;/p&gt;

&lt;p&gt;Llevo 11 años trabajando como DevOps Engineer y recién me animé a vivir esta experiencia de la nube en el &lt;strong&gt;AWS re:Invent 2024&lt;/strong&gt;. El evento oficial ocurrió del &lt;strong&gt;Lunes 2 al Viernes 6 de Diciembre del 2024&lt;/strong&gt;, y la experiencia me encantó tanto, que volví en el 2025 (¡pero esa será otra historia!). &lt;/p&gt;

&lt;p&gt;Ya sea que planees ir en el futuro o quieras conocer cómo es el evento desde adentro, aquí te dejo mis anécdotas, el presupuesto detallado y el gran hito de mi carrera.&lt;/p&gt;

&lt;h3&gt;
  
  
  📍 Empezando la aventura en Las Vegas
&lt;/h3&gt;

&lt;p&gt;El pre-evento sucedió el &lt;strong&gt;Domingo 1 de Diciembre del 2024&lt;/strong&gt;. Una de las primeras cosas que hice al llegar fue dejar mi marca: es un clásico tomarse una foto dinámica junto al enorme muro negro que parece una pizarra, lleno de firmas y el inmenso logo de "re:Invent". &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip pro:&lt;/strong&gt; Recomiendo llegar 1 o 2 días antes de que inicie todo. Esto te da tiempo valioso para aclimatarte, ubicarte en los gigantescos pasillos del centro de convenciones y empezar a respirar el ambiente tecnológico con tranquilidad.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbve10w279bpiszgyk6gh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbve10w279bpiszgyk6gh.jpg" alt="Empecemos" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vh836qnkovogg08ekrt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vh836qnkovogg08ekrt.jpg" alt="Recomiendo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 Una ciudad tomada por la tecnología
&lt;/h3&gt;

&lt;p&gt;Otro punto impresionante es que el re:Invent literalmente se apropia de la ciudad. Durante toda la semana del evento, verás promociones masivas de diferentes herramientas tecnológicas como Logic Monitor, Snyk, Datadog, etc. Las campañas de marketing están por todos lados: desde que aterrizas en el aeropuerto, en los trenes, en los gigantescos paneles a lo largo del Strip de Las Vegas e incluso proyectadas en la imponente &lt;strong&gt;The Sphere&lt;/strong&gt;. ¡Es una inmersión total!&lt;/p&gt;

&lt;h3&gt;
  
  
  🤝 Conectando con la comunidad
&lt;/h3&gt;

&lt;p&gt;El viaje arrancó compartiendo experiencias en el &lt;strong&gt;AWS Community Women Meetup&lt;/strong&gt;. Empezar rodeada de esta gran comunidad te llena de inspiración para afrontar la intensa semana que se viene.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eo7s6cs04og3o82m38v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eo7s6cs04og3o82m38v.jpg" alt="Foto del panel en el " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🏷️ El objeto más valioso: Tu Badge
&lt;/h3&gt;

&lt;p&gt;Grábate esto: &lt;strong&gt;el Badge es lo más importante de todo el evento porque te lo solicitarán en todo momento&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Lo genial es que puedes evitar aglomeraciones recogiendo tu identificación desde el domingo previo al evento. Solo necesitas el QR de tu entrada y puedes hacerlo en el mismo aeropuerto al llegar, o en algunos de los hoteles sede como el Venetian o el MGM. Este año el mío fue súper especial, ya que llevaba mi nombre, mi empresa (Globant) y destacaba mis roles de "Attendee" y "Speaker". ¡Cuídalo como si fuera oro!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2ihfcu1soit09wy4cmr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2ihfcu1soit09wy4cmr.jpg" alt="Tu badge es la única credencial que te permite entrar a todo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🎤 Mi gran hito: ¡Fui Speaker!
&lt;/h3&gt;

&lt;p&gt;Este año no solo fui a aprender, ¡sino a compartir! Tuve el inmenso honor de subirme al escenario como Speaker. &lt;/p&gt;

&lt;p&gt;Me presenté en el &lt;strong&gt;Theater 3&lt;/strong&gt;, donde impartí mi sesión titulada &lt;em&gt;"Amazon EKS: When troubleshooting becomes a months-long journey"&lt;/em&gt;. Fue una experiencia increíble poder compartir con la audiencia los desafíos reales de mi día a día como DevOps Tech Lead. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F334m9jodin6dfrilfwar.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F334m9jodin6dfrilfwar.jpg" alt="Presentando la charla " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📅 La agenda, comida y el "Todo Incluido"
&lt;/h3&gt;

&lt;p&gt;El evento inicia oficialmente el Lunes aproximadamente a las 2:00 PM con un Keynote de apertura y finaliza el Viernes. &lt;/p&gt;

&lt;p&gt;Algo que muchos no saben es que &lt;strong&gt;todo está incluido en tu entrada&lt;/strong&gt;. Durante el evento, tendrás a tu disposición snacks y bebidas por todas partes y durante todo el día. Sin embargo, &lt;strong&gt;¡ojo con la comida principal!&lt;/strong&gt; El desayuno y almuerzo se sirven solo en horarios específicos, ya sea en formato buffet o como &lt;em&gt;lunch box&lt;/em&gt; si necesitas irte corriendo a una charla. &lt;/p&gt;

&lt;p&gt;Si llegas fuera de horario, encontrarás las puertas cerradas (¡me pasó más de una vez!). Pero aquí va un gran salvavidas: hay varios restaurantes en los hoteles que son reservados exclusivamente por sponsors como Datadog, MongoDB y más, en donde puedes desayunar, almorzar y cenar. Recuerda siempre revisar el detalle de los locales reservados para los sponsors para aprovechar estas opciones.&lt;/p&gt;

&lt;p&gt;A pesar de los horarios estrictos, cuando lograba coincidir, aprovechaba estos espacios en la EXPO para hacer una pausa, revisar mi laptop, acomodar mis cosas y recargar energías con un buen plato antes de mi siguiente sesión.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi52o85d21l3kb3egdwru.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi52o85d21l3kb3egdwru.jpg" alt="En la EXPO" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para que no te pierdas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La zona principal de &lt;strong&gt;EXPO&lt;/strong&gt; está en el hotel Venetian.&lt;/li&gt;
&lt;li&gt;Las charlas están distribuidas por todos los hoteles resaltados en el mapa del evento. &lt;/li&gt;
&lt;li&gt;Aprovecha el transporte gratuito (tren o buses) que conectan los distintos hoteles para no caminar todo el Strip.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82x835cjy1o2k2e68wnt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82x835cjy1o2k2e68wnt.jpg" alt="Orientación" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💰 Hablemos de presupuesto
&lt;/h3&gt;

&lt;p&gt;Uno piensa que un evento así puede ser imposible para los que estamos en LATAM o en algún país no dolarizado. Sin embargo, logré aplicar una recomendación clave que me dieron en el AWSome Women Summit 2024: &lt;strong&gt;ahorrar durante los 12 meses del año.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aquí les comparto mi desglose de costos aproximado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vuelo:&lt;/strong&gt; $800 USD (desde Perú)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hotel:&lt;/strong&gt; $1,300 USD (eligiendo uno con convenio con el re:Invent)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transporte/Taxi:&lt;/strong&gt; $100 USD (aeropueto-hotel-aeropuerto) &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comida/Varios:&lt;/strong&gt; $100 USD (para gastos fuera del evento)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entrada:&lt;/strong&gt; $2,000 USD &lt;em&gt;(Tip: Si aplicas y eres parte del programa &lt;a href="https://aws.amazon.com/developer/community/community-builders/" rel="noopener noreferrer"&gt;AWS Community Builders&lt;/a&gt; o User Group Leader, ¡tienes un descuento del 60%!)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total aproximado = $4,300 USD.&lt;/strong&gt; Si lo ahorras en 12 meses, serían unos $350 USD mensuales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Datos adicionales de oro:&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Siempre se abre la beca &lt;strong&gt;&lt;a href="https://aws.amazon.com/events/reinvent/all-builders-welcome/" rel="noopener noreferrer"&gt;All Builders Welcome Grant&lt;/a&gt;&lt;/strong&gt;, que te brinda todo lo mencionado totalmente cubierto y es para cualquier persona. ¡Guarden el link para el próximo año!&lt;/li&gt;
&lt;li&gt;A veces, hablarlo en tu empresa te puede ayudar a pagar el viaje. En mi caso, al mencionar que sería Speaker, mi trabajo cubrió todos mis gastos.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  💡 Recomendaciones doradas y la fiesta AWS re:Play
&lt;/h3&gt;

&lt;p&gt;Sobrevivir a esta semana requiere de estrategia. Mi recomendación estrella es sobre la ropa: &lt;strong&gt;la clave es la comodidad&lt;/strong&gt;. Vas a caminar muchísimo, así que usa zapatillas que ya tengas. ¡Por favor, no lleves zapatillas nuevas! Tomará tiempo que se adapten a ti y tus pies sufrirán. &lt;/p&gt;

&lt;p&gt;Además, te sugiero:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Máximo 1 o 2 charlas por día&lt;/strong&gt; para no saturarte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Considera las distancias&lt;/strong&gt; de los traslados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y claro, ¡el Jueves es la fiesta oficial conocida como &lt;strong&gt;AWS re:Play&lt;/strong&gt;! Es el evento perfecto para celebrar, disfrutar de los escenarios con luces, tomarte fotos con tu equipo y despedir la semana a lo grande (¡y también está incluida en tu entrada!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfa81zxp4x17hbsvc0ri.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfa81zxp4x17hbsvc0ri.jpg" alt="En el AWS re:Play con colegas de Latinoamérica" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🍓 Recargando energías
&lt;/h3&gt;

&lt;p&gt;Siempre hay espacio para relajarse y divertirse. ¡Encontrarás diferentes stands y actividades a lo largo de todos los hoteles del evento!&lt;br&gt;
. En mi caso, aproveché para jugar el juego interactivo "BuilderCards" con otros asistentes, tomarme una foto junto a la gran mascota verde (el bucket de AWS), ¡y hasta me deslicé con los brazos en alto por un enorme tobogán morado al lado de las escaleras mecánicas!&lt;br&gt;
.&lt;br&gt;
Recorrer la zona de la EXPO es una locura: te puedes cruzar con un simulador de golf, gigantescas maquetas tipo Lego que incluyen hasta una montaña rusa amarilla, y pasear entre inmensos stands de patrocinadores como CockroachDB y Okta&lt;br&gt;
.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjvch0spuxth7h0np0ss.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjvch0spuxth7h0np0ss.jpg" alt="Lo que encontrarás" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧳 La regla de oro final: Maleta vacía para el SWAG
&lt;/h3&gt;

&lt;p&gt;Todo asistente veterano te lo dirá: &lt;strong&gt;tienes que llevar una maleta vacía&lt;/strong&gt;. La cantidad de mercadería promocional que consigues en la EXPO es una locura. Logré llenarla con peluches, calcetines coloridos, libretas, botellas, camisetas y muchos pines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh3cio5bzx39cz2nuxc2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh3cio5bzx39cz2nuxc2.jpg" alt="Foto de la montaña de SWAG sobre la cama" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🗓️ ¡Prepárate para el próximo re:Invent!
&lt;/h3&gt;

&lt;p&gt;Un último súper dato: apenas termina cada edición del re:Invent, automáticamente se publican las fechas para el evento del año siguiente. Así que si te animaste a ir con este post, puedes revisar cuándo será la próxima edición y empezar a planificar desde hoy mismo visitando su página oficial: &lt;a href="https://aws.amazon.com/events/reinvent/" rel="noopener noreferrer"&gt;https://aws.amazon.com/events/reinvent/&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¡Sigamos conectados!
&lt;/h3&gt;

&lt;p&gt;¡Gracias a todos los que hicieron de este evento una experiencia inolvidable! Me encantaría seguir la conversación con ustedes sobre la nube y DevOps. &lt;/p&gt;

&lt;p&gt;Pueden encontrarme en:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dev.to / Redes:&lt;/strong&gt; &lt;a class="mentioned-user" href="https://dev.to/carotechie"&gt;@carotechie&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://linkedin.com/in/carolinahm" rel="noopener noreferrer"&gt;linkedin.com/in/carolinahm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¡Nos vemos en la nube! ☁️✨&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7846t4m9kxojqcbvho6j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7846t4m9kxojqcbvho6j.jpg" alt="Gracias por leer :)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>career</category>
      <category>womenintech</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
