Containerizing Your App with AWS ECR, EC2, ECS, Fargate & Load Balancer: A Step-by-Step Guide:

Table of contents

My DevOps First Win!
Hey hey DevOps fam! 👋🏾
Let me gist you about how I brought my little frozen food website — Veget Foods — to life using Docker and AWS.
This was my first ECS (EC2 launch type) deployment and guess what? I did it manually, step-by-step, like a real DevOps engineer. 😎
“Containers don’t have to be complicated — especially on AWS.”
If you’ve ever wanted to deploy a containerized application on AWS without battling Kubernetes complexity, you’re in the right place.
In this guide, I’ll walk you through building, pushing, and running your app using Amazon ECS with the EC2 launch type, plus an Application Load Balancer for smooth, high-availability access.
We’ll cover everything step-by-step so you can follow along — whether you’re a DevOps newbie or just exploring AWS container services.
If you’re on the DevOps learning path like me and want to see what deploying a real website looks like, this post is for you.
🧾 The Backstory
I had this simple HTML site for Veget Foods, my frozen food brand. Nothing fancy, just a welcome message. But I wanted more than just viewing it locally.
I wanted to:
✅ Package it in a Docker container
✅ Push it to ECR
✅ Run it on ECS (EC2 launch type)
✅ Set up a Load Balancer (ALB)
✅ And of course… show it off publicly 😁
So, I rolled up my sleeves and went all in. Let me walk you through how I did it — mistakes, wins, and lessons included.
🌟 Why ECS Over EKS?
AWS gives you two main container orchestration options:
ECS (Elastic Container Service) – Perfect if you want a fully managed, straightforward solution without having to manage Kubernetes yourself.
EKS (Elastic Kubernetes Service) – Ideal if you need the flexibility and complexity of Kubernetes.
For this project, I went with ECS (EC2 launch type) — meaning I managed the EC2 instances myself but still let ECS handle container orchestration.
🧩 AWS ECS in a Nutshell
Think of ECS as AWS’s brain for managing your containers. It:
Runs and scales Docker containers across multiple Availability Zones
Works with EC2 (you manage servers) or Fargate (AWS manages servers for you)
Integrates with IAM, VPC, CloudWatch, ECR, CodePipeline, and Load Balancers
Offers auto-scaling out of the box
🏗 ECS Building Blocks
Here’s what makes up an ECS deployment:
Cluster → A logical group where your containers run
Task Definition → The blueprint for your app (image, CPU, memory, networking, etc.)
Tasks → Running instances of your Task Definition
Service → Ensures the desired number of tasks are running and restarts failed ones
Container Instances → EC2 machines or serverless Fargate tasks where containers live
🛠 What We’ll Do in This Project
We’re going to:
Containerize our application
Push our image to Elastic Container Registry (ECR)
Create an ECS Cluster with Task Definitions and Services
Set up IAM Roles and Security Groups
Deploy with an Application Load Balancer (ALB)
By the end, you’ll be able to hit your app’s DNS name and see it live.
🧰 Tools I Used
Docker – for containerizing the app
Amazon ECR – to store the Docker image
Amazon ECS (EC2) – to run the containers
EC2 Instance – compute power
Application Load Balancer (ALB) – for public access and traffic routing
Target Group – for directing traffic to tasks
🛠️ Step-by-Step Deployment
🚀 Step 1: Spin Up an EC2 Instance
Create an EC2 instance. (See AWS EC2 Instance Launch if you need help.)
Under Network Settings, create a new Security Group and add an HTTP inbound rule (Type: HTTP, Source: 0.0.0.0/0).
- Launch your instance.
🔑 Step 2: Connect to EC2
You can connect via:
Instance Connect (browser-based terminal)
SSH Client (requires your EC2 key pair)
For SSH:
ssh -i "your-key.pem" ec2-user@<your-ec2-public-ip>
sudo su
yum update -y
Then: enter root and update:
sudo su , yum update -y
. Thesudo su
command takes you to the root user andyum update -y
, updates your Amazon Linux.
🐳 Step 3: Install Docker
To install docker, you have to run the following commands. curl -fsSL
https://get.docker.com
-o
get-docker.sh
, yum install docker -y, systemctl start docker
After successfully installing docker, we use the systemctl start docker
to start docker, then run systemctl status docker
to know the status of docker. From the diagram below, you would realize that docker is started, active and running.
To continue with your commands, type Q and it takes you to the root folder again.
Create a project directory:
mkdir veget_foods && cd veget_foods
📂 Step 4: Build App & Dockerfile
b. Type vi dockerfile
to create dockerfile and input the code below
Here is my Dockerfile:
Type vi Index.html to create your html file. Put in your code, save and exit.
Login to your docker account by typing docker login
and inputting all the necessary information. :docker login
📂 Step 5: Build the Docker Image
Run the command docker build -t veget-foods .
to build the docker image
🗝 Step 6: Configure AWS CLI
In AWS Console: IAM → Users → Create Access Keys (for CLI use).
Select CLI as your use case.
Select confirmation box - Next - Create access keys.
After creating the access keys, navigate back to the terminal and type aws configure
, Enter your Access Key, Secret Key, region, and output format when prompted
🏷 Step 7: Create ECR Repository
aws ecr create-repository --repository-name veget-repo
Copy the repository URI from the AWS Console.
After creating the repository, you can confirm on AWS Console. Click on the repository that has just been created. Next, click View Push Commands and a dialog box would be opened.
Step 8: Push to Amazon ECR
Logged into ECR: Run these commands on the terminal to tag and push your image to Amazon ECR.
aws ecr get-login-password | docker login --username AWS --password-stdin <your-ecr-url>
Tagged the image:
docker tag veget-repo:latest <your-ecr-url>/veget-repo:latest
Then pushed it:
docker push <your-ecr-url>/veget-repo:latest
Image ✅ in ECR!
🖥 Step 9: Create ECS Cluster & Task Definition
ECS Console → Create Cluster → EC2 Linux + Networking
Name it
veget-cluster
(or another unique name).Under Task Definitions → Create New:
Name:
veget_task_dev
Launch type: EC2
Container name: veget-container
Image: Your ECR image URI
Port mapping: 80 → 80Create a container to run Your image by running the command in the diagram below.
# run the container in the background, map host port 80 -> container port 80
docker run -d --name veget-container -p 80:80 veget-foods
# check running containers
docker ps
ECS Cluster Setup (EC2 Launch Type)
Inside the ECS Console:
Created a cluster using "EC2 Linux + Networking"
Named it
veget-cluster
Chose
t2.micro
for testing (Free Tier friendly)Selected my key pair and default VPC/subnets
Under ECS > Task Definitions:
Name:
veget_task_dev
Launch type: EC2
Container name:
veget-container
Image: My ECR image URL
Port mapping: Container 80 → Host 80
Saved and registered it
⚖ Step 10: Set Up Load Balancer
Go to EC2 → Load Balancers → Create.
Name:
veget-alb
, Scheme: Internet-facing, Listener: Port 80.
b. Give your load balancer a name,ensure it is internet facing. Leave the other parts as default and move to Network mapping.
c. Under Network mapping, select the VPC. In my case, it was the default VPC and I selected 2 AZs which automatically attached the subnets.
d. Under Security groups, click on the drop down arrow and select the security group you created when creating the EC2.
e. Under Listeners and routing, select Create Target group.
Create Target Group:
Type: IP
Protocol: HTTP, Port: 80
Health check path:
/index.html
: This helps ALB know if your app is healthy or not.
Attach Target Group to the ALB
Give the Target group a name.
Move to Advanced health check settings and scroll to Healthy threshold.
Click Next
Select your instance, next select Create Target group.
Return to Listener and routing so that you can add the load balancer.
Now create the load balancer:
Now the juicy part — making the site public!
Created a new ALB
Name:
veget-alb
Scheme: Internet-facing
Listener: Port 80
Waited a bit for provisioning...
🛡 Step 11: Create an ECS Task Role
In IAM → Roles:
Select AWS Service.
Choose Elastic Container Service.
Attach relevant policies.
Checking for role created
🚀 Step 12: Deploy Service
In ECS Console: Create ECS Resources
Go to ECS → Task Definitions → Create New.
Use the Task Role you just made.
Add a container pointing to your ECR image.
Create a Cluster.
Create a Service in that cluster:
Select your Task Definition.
Desired tasks: 2.
Enable Load Balancing.
Back in ECS > Clusters > veget-cluster
> Services:
Launch type: EC2
Task def:
veget_task_dev
Service name:
veget_task_dev-service
Tasks: 2
Attached to the Load Balancer
Selected the right listener
Selected the right target group
Hit create… and crossed my fingers 🤞🏾
✅ Step 13: Test Your Deployment
Grab your ALB DNS name, paste it in your browser… and there’s your app 🎉
If it doesn’t work, check:
Target Group health
Security Group inbound rules
It Worked!! 🎉
Visited the ALB DNS name, and boom 💥 — my Veget Foods website was live on the internet. Just like that!
😵 What Went Wrong?
Oh, trust me — it wasn’t all smooth. Here are a few hiccups:
❌ “Circuit breaker triggered”
This scared me at first, but it just meant the container didn’t pass the health check. I had forgotten to update the health check path in the target group to /index.html
.
❌ Target group was empty
Make sure you use IP as the target type and that the tasks actually start and run correctly on EC2.
❌ Website not loading?
Check your security group and open port 80 to 0.0.0.0/0
.
I had to tear everything down and start afresh — delete task definitions, target groups, load balancer, and all. But that’s part of learning! 💪🏾
🧠 Key Lessons I Learned
ECS (EC2) is a great way to learn container orchestration manually.
ALB and Target Groups need to be properly configured for your service to be reachable.
Don’t panic when stuff breaks. Delete. Rebuild. Learn. 🔁
📸 Here's Proof
Look at that screen! My site, running from a container, on ECS, behind an ALB. Proud DevOps moment. ❤️🔥
🎯 Final Words
Deploying the Veget Foods website using Docker, Amazon ECS (EC2), and an Application Load Balancer was a rewarding journey that provided valuable insights into container orchestration and cloud deployment. This hands-on experience highlighted the importance of meticulous configuration, especially with ALB and Target Groups, to ensure seamless access to the application.
Despite encountering challenges like health check failures and security group misconfigurations, the process reinforced the value of persistence and iterative learning.
This project not only boosted my confidence in handling real-world DevOps tasks but also underscored the potential of ECS as a powerful tool for managing containerized applications. For anyone on a similar learning path, embracing the trial-and-error process is key to mastering these technologies.
So if you’re also learning DevOps, don’t be scared of ECS — dive in, break things, fix them, and deploy your own project!
Have any questions, or trying this yourself? Drop your comments — I’m happy to help!
Until the next deployment,
Betty Musari 💜
Subscribe to my newsletter
Read articles from Funmilola Elizabeth Opeyemi Musari directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Funmilola Elizabeth Opeyemi Musari
Funmilola Elizabeth Opeyemi Musari
👋 Hi, I’m Betty Musari — a former food scientist now diving deep into the world of DevOps and cloud engineering. I write about my hands-on journey with AWS, Docker, and CI/CD, translating complex concepts into clear, beginner-friendly stories. With a scientific mindset and a passion for continuous learning, I'm on a mission to demystify the cloud — one container at a time. ✨As a Food Technologist & Sales Strategist turned DevOps Explorer, I leverage problem-solving and client-centric skills to build resilient cloud systems. Currently mastering CI/CD pipelines, Azure, and Infrastructure as Code (Terraform) to automate deployments like a well-oiled production line. Passionate about merging operational efficiency with technical innovation—because great systems, like great recipes, require precision and scalability.