DEV Community

Cover image for Deploy a Container on AWS with ECR and ECS (Fargate): Beginner's Guide
Vishal Patil
Vishal Patil

Posted on

Deploy a Container on AWS with ECR and ECS (Fargate): Beginner's Guide

Push a Docker image to Amazon ECR and run it on ECS with Fargate, step by step, with CLI commands and common errors."

tags: aws, docker, devops, containers

Running a container on your laptop is easy. Running it reliably in the cloud means you need somewhere to store images and something to run, restart, and scale them. On AWS, that's Amazon ECR and Amazon ECS.

In this post I'll explain what each does and walk through deploying a containerized app on Fargate, so there are no servers to manage.

ECR vs ECS in one minute

Amazon ECR (Elastic Container Registry) is a private, managed registry for your container images. Think of it as a Docker Hub that lives inside your AWS account, with IAM-based access control, vulnerability scanning, and lifecycle policies.

Amazon ECS (Elastic Container Service) is the orchestrator. You describe what to run, and ECS places it, restarts it if it fails, and keeps the desired number of copies running.

Concept What it is
Cluster Logical grouping of tasks and services
Task definition Blueprint: image, CPU, memory, ports, env vars, roles
Task A running instance of a task definition
Service Keeps N tasks running and replaces failed ones
Fargate Serverless compute for containers, no EC2 to manage

The flow looks like this:

docker build → docker push → ECR (stores image)
                                ↓
              ECS task definition points to the image URI
                                ↓
              ECS service runs tasks on Fargate
Enter fullscreen mode Exit fullscreen mode

Prerequisites

  • An AWS account
  • AWS CLI configured (aws configure)
  • Docker installed
  • A small app with a Dockerfile (Nginx or Node.js is fine)

Step 1: Create the ECR repository

aws ecr create-repository \
  --repository-name my-app \
  --region ap-south-1
Enter fullscreen mode Exit fullscreen mode

Copy the repositoryUri from the output. It looks like <account-id>.dkr.ecr.ap-south-1.amazonaws.com/my-app.

Step 2: Build, tag, and push the image

# Build
docker build -t my-app .

# Authenticate Docker to ECR
aws ecr get-login-password --region ap-south-1 | \
docker login --username AWS --password-stdin \
<account-id>.dkr.ecr.ap-south-1.amazonaws.com

# Tag and push
docker tag my-app:latest <account-id>.dkr.ecr.ap-south-1.amazonaws.com/my-app:latest
docker push <account-id>.dkr.ecr.ap-south-1.amazonaws.com/my-app:latest
Enter fullscreen mode Exit fullscreen mode

Check the ECR console and you should see the image with the latest tag.

Step 3: Create an ECS cluster

In the ECS console, choose Clusters → Create cluster, name it my-app-cluster, keep AWS Fargate (serverless) selected, and create it.

Step 4: Create the task definition

  1. Task definitions → Create new task definition
  2. Name: my-app-task, launch type: AWS Fargate
  3. Size: for example 0.5 vCPU / 1 GB for a small app
  4. Task execution role: ecsTaskExecutionRole
  5. Add a container with your ECR image URI and container port (for example 80)
  6. Leave CloudWatch logging enabled

Step 5: Run it as a service

  1. Open the cluster → Services → Create
  2. Launch type: Fargate, pick your task definition
  3. Desired tasks: 1 (use 2 for availability)
  4. Choose your VPC and subnets
  5. Use a security group that allows inbound traffic on the container port
  6. Create the service

Step 6: Test it

When the task shows RUNNING, open it, copy the public IP, and visit http://<public-ip>. Your container is live.

Task role vs task execution role

This trips up a lot of beginners:

  • Task execution role: used by ECS itself to pull the image from ECR and write logs to CloudWatch
  • Task role: used by your app code inside the container to call AWS services (for example, reading from S3)

Keep both as narrow as possible.

Troubleshooting

Problem Likely cause
CannotPullContainerError Execution role missing permissions, wrong image URI, or no network path to ECR (needs a public IP or NAT/VPC endpoints)
Task keeps stopping App crashes on startup. Check CloudWatch logs and the exit code
Can't reach the app Security group doesn't allow the container port, or the task has no public IP
Service stuck at 0 running tasks Check the service Events tab for the exact error

Best practices

  • Don't deploy latest to production. Tag images with a version or commit hash
  • Turn on scan on push in ECR
  • Add lifecycle policies to expire old untagged images
  • Put an Application Load Balancer in front and run tasks in private subnets for production
  • Use least-privilege IAM roles
  • Store secrets in Secrets Manager or SSM Parameter Store, never as plain text in the task definition

Wrapping up

ECR gives your images a secure home, and ECS on Fargate runs them without any server management. Once images, task definitions, and services click, you have the foundation for production-ready container workloads on AWS. A good next step is adding an ALB and auto scaling, then automating the build-and-deploy flow with CI/CD.

If you found this useful, let me know in the comments what you'd like me to cover next.


Connect with me

vishalcloudjourney

Top comments (0)