Run containerized apps on AWS: push images to ECR, run them on ECS with the serverless Fargate launch type, define tasks and services, and understand when to reach for EKS (managed Kubernetes) instead.
Containers package an app with everything it needs to run. AWS gives you: ECR (a registry to store images), ECS (AWS's own orchestrator that runs them), Fargate (run containers with no servers to manage), and EKS (managed Kubernetes). Why: ECS+Fargate is the simplest path; EKS is for teams already invested in Kubernetes.
echo "ECR = store container images"echo "ECS = run/orchestrate containers (AWS-native)"echo "Fargate = a launch type: containers without managing servers"echo "EKS = managed Kubernetes, if you need the Kubernetes ecosystem"ECR (Elastic Container Registry) is a private Docker registry in your account. Why: ECS and EKS pull images from somewhere — ECR is the secure, AWS-integrated place to push them. You log Docker in to ECR, then push like any other registry.
Create a repository
aws ecr create-repository --repository-name my-appLog Docker in to ECR (uses your AWS credentials)
aws ecr get-login-password | docker login --username AWS \
--password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.comTag and push a local image
docker tag my-app:latest \
111122223333.dkr.ecr.us-east-1.amazonaws.com/my-app:latestdocker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/my-app:latestA cluster is the logical group your containers run in. A task definition is the blueprint for a running unit: which image(s), how much CPU/memory, ports, env vars. Why: ECS reads the task definition to know exactly how to start your container — it is the container equivalent of a launch template.
Create a cluster
aws ecs create-cluster --cluster-name my-clusterA Fargate task definition (the container blueprint). Save as task-def.json
{
"family": "web",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256", "memory": "512",
"containerDefinitions": [{
"name": "web",
"image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/my-app:latest",
"portMappings": [{ "containerPort": 80 }]
}]
}aws ecs register-task-definition --cli-input-json file://task-def.jsonFargate is a "launch type" that runs your task without you managing any EC2 servers — AWS provides the compute, you just say how much CPU/memory. Why: no cluster of servers to patch or scale; you pay per task for the resources it uses. It is the easiest way to run containers on AWS.
Run a one-off task on Fargate in your private subnet
aws ecs run-task --cluster my-cluster \
--launch-type FARGATE \
--task-definition web \
--network-configuration 'awsvpcConfiguration={subnets=['$PRIVATE_SUBNET'],securityGroups=['$SG_ID'],assignPublicIp=DISABLED}'A one-off task exits when done. A service keeps a desired number of tasks running, replaces failed ones, and registers them with a load balancer. Why: this is how you run a long-lived web app on ECS — the container equivalent of an Auto Scaling group + ELB.
Run 2 copies of the task, fronted by the target group from earlier
aws ecs create-service --cluster my-cluster \
--service-name web-svc \
--task-definition web \
--desired-count 2 \
--launch-type FARGATE \
--load-balancers 'targetGroupArn='$TG_ARN',containerName=web,containerPort=80' \
--network-configuration 'awsvpcConfiguration={subnets=['$PRIVATE_SUBNET'],securityGroups=['$SG_ID']}'EKS (Elastic Kubernetes Service) runs the Kubernetes control plane for you. Why choose it: if your team already uses Kubernetes tooling (kubectl, Helm, existing manifests) or needs its portability across clouds. Note: it is more moving parts than ECS — reach for it when you specifically want Kubernetes.
The eksctl tool is the easiest way to stand up a cluster
eksctl create cluster --name my-eks --region us-east-1 --fargateOnce up, kubectl is configured automatically — run normal Kubernetes:
kubectl get nodeskubectl create deployment web --image=nginxkubectl get pods