🐳 Deploying a Containerized Web App on AWS using ECS Fargate, ECR, and Load Balancer (Step-by-Step Guide)

Are you curious about how to run your application in the cloud without worrying about managing servers or learning complex tools like Kubernetes? You're in the right place.

In this guide, I’ll walk you through containerizing a simple web app and deploying it on AWS using tools like ECS Fargate, ECR, EC2, and a Load Balancer. Don’t worry if these terms sound unfamiliar—we’ll break them down and make them easy to understand.

By the end of this tutorial, you’ll have a live application running in the cloud with high availability, no server maintenance, and automatic scaling handled for you.

🧰 Key AWS Tools We'll Be Using (Explained Simply)

  • EC2 (Elastic Compute Cloud): A virtual machine in the cloud. We'll use this to build and test our Docker image before deployment.

  • Docker: A tool to package our app and its environment into a "container" so it runs the same anywhere.

  • ECR (Elastic Container Registry): AWS’s private storage for your Docker images. Think of it as your container's home on the cloud.

  • ECS (Elastic Container Service): AWS’s way of running and managing containers. It works with either your own servers (EC2) or AWS-managed infrastructure (Fargate).

  • Fargate: A server less option that lets you run containers without managing any servers at all. AWS handles all the heavy lifting.

  • IAM (Identity and Access Management): Used to create roles and permissions for secure access to services.

  • Application Load Balancer (ALB): Distributes traffic across multiple instances of your app to ensure availability and prevent downtime.

🚀 What We'll Be Doing

Here’s a high-level view of the steps we’ll follow in this project:

  1. Launch an EC2 instance to install Docker and build our app.

  2. Containerize a simple web application with a Dockerfile and HTML page.

  3. Push the Docker image to AWS ECR.

  4. Set up ECS using Fargate to deploy the container.

  5. Create an Application Load Balancer for routing traffic.

  6. Set up roles and permissions using IAM.

  7. Deploy the app and test it live using your Load Balancer DNS.

Whether you're new to cloud infrastructure or just want a smoother deployment process, this tutorial is for you. Let's get started!

🖥️ Launching an EC2 Instance to Install Docker and Build Our App

Before we containerize our app and push it to the cloud, we’ll need an environment to build and test it. In this case, we’ll use an EC2 instance Amazon’s virtual server—to install Docker and package our application.

Here’s how to get started:

🔧 Step 1: Launch an EC2 Instance

  1. Head over to your AWS Management Console and search for EC2.

  2. Click “Launch Instance”.

  3. Give your instance a name. (I called mine shepherd for this project.)

  4. Leave most of the default settings as they are.

  5. Under Key Pair (Login), create a new key pair and download the .pem file (you’ll use it later to connect).

  6. Scroll down to Network Settings and click “Edit”.

    • Under Security Group, create a new one.

    • Add an inbound rule for HTTP with 0.0.0.0/0 as the source to allow web traffic.

Once that’s done, scroll down and click “Launch Instance.”

🧑‍💻 Step 2: Connect to Your Instance

Once the instance is up and running:

  1. Go to your EC2 dashboard, select your instance, and click “Connect.”

  2. You can use either Instance Connect (opens a browser terminal) or your local SSH client.

    • For SSH, open your terminal or PowerShell and use the command below:

        ssh -i "path-to-your-key.pem" ec2-user@your-ec2-public-ip
      

🐳 Step 3: Install Docker

Once connected to the instance:

  1. Switch to the root user:

     sudo su
    
  2. Update your packages:

     yum update -y
    
  3. Download the Docker install script:

     curl -fsSL https://get.docker.com -o get-docker.sh
    
  4. Install Docker:

     yum install docker -y
    
  5. Start Docker and confirm it’s running:

     systemctl start docker
     systemctl status docker
    

    You should see a green “active (running)” message. Press Q to exit status view.

    1. Log into docker

      To log in to Docker via the terminal, you can use the following command:

       docker login
      

      After running this command, you’ll be prompted to enter your Docker Hub username and password.

      🧱 Step 4: Create Your App Files

  1. Create a working directory:

     mkdir shepherd-app
     cd shepherd-app
    
  2. Create a simple Dockerfile:

     vi Dockerfile
    

    Paste the following inside:

     FROM almalinux:8
    
     RUN dnf install -y httpd && dnf clean all
    
     COPY index.html /var/www/html/
    
     CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
    
     EXPOSE 80
    
    • Press Esc, then type :wq to save and exit.
  3. Create your index.html:

     vi index.html
    

    Before pasting, type:

     :set paste
    

    Then paste in your HTML. For testing, a simple message like this is fine:

     <h1>Hello!</h1>
    
  4. Confirm the file was saved:

     cat index.html
    

🧪 Step 5: Build and Run Your Docker Container

  1. Build the Docker image:

     docker build . -t dinrei_img
    
  2. Run the image in a container:

     docker run -d -p 80:80 --name dinrei_container dinrei_img
    
  3. Confirm it’s running:

     docker ps
    
  4. Now, go back to your EC2 dashboard, copy the Public IPv4 address, and paste it in your browser. You should see your custom HTML page displayed!

    Copying the IPv4 address should load up your site on your browser


    📦 Pushing Your Docker Image to AWS ECR (Elastic Container Registry)

    Now that your application is containerized and running on EC2, the next step is to upload your Docker image to Amazon ECR. ECR is AWS’s private Docker image repository—it’s where ECS pulls images from during deployment.

    🧭 Step 1: Create an IAM Role and Access Keys

    To interact with AWS from your EC2 instance (via the CLI), you'll need to create programmatic credentials.

    1. Go to the IAM service in your AWS Console.

    2. Navigate to Users → select the IAM user created.

    3. Click on “Create access key

    4. Under the Security credentials tab, click “Create access key.”

    5. The access key will be downloaded it your PC in an excel spreadsheet.

    6. Copy the Access key ID and Secret access key somewhere safe.

🔐 Step 2: Configure the AWS CLI

Back in your EC2 terminal:

    aws configure

You’ll be prompted to enter:

  • Access key ID

  • Secret access key

  • Default region name (e.g. us-east-1, eu-north-1, or your specific region)

  • Default output format (you can leave this as json or press Enter)

🗂️ Step 3: Create a Repository in ECR

Still on the EC2 terminal, run:

    aws ecr create-repository --repository-name dinrei_img

This creates a private repository for your Docker image. You can confirm it on the AWS Console under ECR > Repositories.

🔑 Step 4: Authenticate Docker to ECR

Run this command to log Docker into ECR using your credentials:

    aws ecr get-login-password --region <your-region> | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.<your-region>.amazonaws.com

Replace:

  • <your-region> with your AWS region (e.g. eu-north-1)

  • <your-account-id> with your AWS account number

🏷️ Step 5: Tag and Push Your Image

First, access your EC2 instance to run the following Docker commands:

  1. Go to the EC2 Dashboard.

  2. Click on the EC2 instance you created.

  3. Click Connect and choose the EC2 Instance Connect (browser-based CLI) option.

  4. Once inside the terminal, run the commands displayed there.

Tag your image so it matches your ECR repository:

    docker tag dinrei_img:latest <your-account-id>.dkr.ecr.<your-region>.amazonaws.com/dinrei_img:latest

Push the image to ECR:

    docker push <your-account-id>.dkr.ecr.<your-region>.amazonaws.com/shepherd_img:latest

✅ After the push, your image is now in Amazon ECR and ready to be pulled by ECS during deployment.


Before moving on, grab the public IPv4 address of your EC2 instance, open your browser, and check if your containerized app is still running:

    http://<your-public-ip>

If it loads your app, then everything is good.


🌐 Setting Up ECS Fargate to Deploy the Container

Now that your image is stored in ECR, it’s time to deploy using ECS with Fargate — no server management, AWS handles scaling for you.

🛰️ Step 1: Create a Load Balancer

  1. Go to EC2 > Load Balancers.

  2. Click Create Load Balancer.

  3. Select Application Load Balancer.

  4. Name your load balancer — e.g., dinrei_load_balancer.

  5. Scheme: Select Internet-facing.

  6. Network mapping:

    • VPC: Select the default VPC.

    • Availability Zones: Select at least two.

  1. Security Groups:

    • Select the one created with your EC2 instance — e.g., dinrei-wizard-1.

  1. Listeners and Routing:

    • Protocol: HTTP

    • Port: 80


🎯 Step 2: Create a Target Group

Since no target group exists yet:

  1. On the load balancer creation page, under Target Group, select Create Target Group.

  2. Target type: Instances

  3. Name: e.g., dinrei_target_group

  4. Protocol: HTTP | Port: 80

  5. IP Address type: IPv4

  6. Leave everything else as default and click Next.

  7. Select your running instance and register it.

  8. Complete creation and return to the Load Balancer setup.

  9. Select the newly created target group and finalize creating the Load Balancer.


🔐 Step 3: Create an IAM Role for ECS

  1. Go to IAM > Roles > Create Role.

  2. Trusted entity type: AWS Service.

  3. Use case: Elastic Container Service > Elastic Container Service Task.

  4. Permissions: Add the following policies:

  5. Leave the rest as is and create the role.


🧱 Step 4: Create a Task Definition

  1. Go to ECS > Task Definitions > Create New Task Definition.

  2. Launch Type: AWS Fargate.

  3. Task Name: e.g., dinrei-task.

  4. Task Role: Select the IAM role created above.

  5. Go to ECR > Private Registry > Repositories and copy your image URI.

  6. Under Container Definitions, click Add Container:

    • Name: e.g., container-1

    • Image: Paste the image URI from ECR.

    • Port mapping: 80

  7. Click Create to finish.


📦 Step 5: Create an ECS Cluster

  1. Go to ECS > Clusters > Create Cluster.

  2. Give it a name — e.g., dinrei-cluster.

  3. Leave all other settings as default and create.


⚙️ Step 6: Create a Service

  1. In your ECS cluster, go to the Services tab > Click Create.

  2. Task Definition: Select the one you created (dinrei-task).

  3. Service type: Replica

  4. Desired tasks: 2

  5. Turn on Availability Zone Rebalancing.

  6. VPC: Choose the default VPC.

  7. Subnets: Select at least two subnets.

  8. Security group: Choose existing and select your previously used group.

🔗 Load Balancing

  • Select Use an existing load balancer.

  • Choose the load balancer you created earlier.

  • For listeners: HTTP:80

  • Under Target group:

    • Select Create new target group.

    • Name: e.g., dinrei-task-group

    • Protocol: HTTP

    • Deregistration delay: 300

    • Evaluation order: 2

    • Health check protocol: HTTP

  • Leave the rest as default and click Create.

You’ll now see the service created in your cluster, and it should show your two tasks running.

Based on the images above, all deployments completed successfully.
I then copied the IPv4 address of my EC2 instance, accessed it in my browser, and here’s the result:

I retrieved the DNS of my load balancer and attempted to access it, I encountered an error.


🧪 Step 7: Register the EC2 Instance with Target Group

To fix the issue, we need to register the target group. From the screenshot below you’ll notice the target is zero which is causing this error.

  1. Go to EC2 > Target Groups.

  2. Select the one you created — e.g., dinrei-target-group.

  3. Scroll to Registered Targets.

  4. If empty, click Register Target.

  5. Select your running EC2 instance.

  6. Click Include as pending, then Register pending targets.

  7. Confirm that total targets = 1.


✅ Step 8: Verify Deployment

  1. Go to EC2 > Load Balancers.

  2. Select your load balancer and go to Resource Map.

  3. Confirm that your target group is linked.

  4. Scroll to the DNS Name of the load balancer.

  5. Paste it into your browser.

🎉 You should now see your deployed application live on Fargate!


✅ Final Summary

You’ve now successfully:

  • 🐳 Containerized your app and pushed it to ECR

  • 📦 Deployed it to Fargate without managing servers

  • 🌍 Made it publicly accessible through an Application Load Balancer

  • 🔐 Secured it via a security group and public subnet configuration

This is a scalable, production-ready cloud deployment, and you can now easily scale your service by increasing the task count or adding autoscaling rules.

Thanks for checking out my blog post—I hope it helped guide you through the process clearly!

Feel free to like, follow, and drop a comment to share your thoughts or questions about the project.

I’d love to hear your feedback!

0
Subscribe to my newsletter

Read articles from Di Nrei Alan Lodam directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Di Nrei Alan Lodam
Di Nrei Alan Lodam