ECS on Fargate is the simplest production path from a container image to a scalable, load-balanced service on AWS.
Amazon ECR is the private image registry. Authenticate Docker with aws ecr get-login-password | docker login --password-stdin <account>.dkr.ecr.<region>.amazonaws.com, then tag and push. Enable scan on push and use lifecycle policies to expire old images.
Amazon ECS concepts:
- A task definition is the versioned blueprint: containers, image, CPU and memory, ports, environment, secrets (from Secrets Manager or Parameter Store), log configuration and health check, plus two IAM roles: the task role your code uses and the task execution role ECS uses to pull images, fetch secrets and write logs.
- A task is a running instance of a task definition.
- A service keeps N tasks running, registers them with a load balancer target group, replaces failed tasks, scales with Application Auto Scaling and performs deployments.
- A cluster groups services and capacity.
Capacity comes from Fargate (serverless: pay per task vCPU and memory, no instances to patch) or EC2 capacity providers (cheaper at scale, GPUs, more control). Fargate Spot runs interruptible tasks at a discount.
With the awsvpc network mode (required on Fargate) each task gets its own ENI, private IP and security group, so SG-to-SG rules work per service.
Deployments are rolling by default; enable the deployment circuit breaker with rollback so a bad image is automatically reverted. ECS Service Connect adds service discovery and traffic metrics between services.
Example
{
"family": "orders-api",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "512",
"memory": "1024",
"runtimePlatform": {"cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX"},
"executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::111122223333:role/orders-api-task",
"containerDefinitions": [{
"name": "api",
"image": "111122223333.dkr.ecr.eu-west-1.amazonaws.com/orders-api:1.4.2",
"portMappings": [{"containerPort": 8080}],
"secrets": [{"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:prod/orders/db-AbCdEf:password::"}],
"logConfiguration": {"logDriver": "awslogs", "options": {
"awslogs-group": "/ecs/orders-api", "awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "api"}},
"healthCheck": {"command": ["CMD-SHELL", "curl -f http://localhost:8080/healthz || exit 1"],
"interval": 30, "retries": 3}
}]
}Remember
- ECR stores images; ECS runs them from versioned task definitions
- Service = desired count + load balancer + deployments
- Task role for your code, task execution role for ECS itself
- Fargate removes servers; awsvpc gives each task its own ENI and SG
Watch out for
- Using mutable tags like latest in task definitions, so you can't tell or roll back what is running.