AWS Containers
ECR
Managed container image registry for Docker images and OCI artifacts
Amazon Elastic Container Registry (ECR) is a fully managed Docker container registry that stores, manages, and deploys container images and OCI artifacts. ECR integrates natively with ECS, EKS, and CodePipeline, eliminating the need to run your own registry infrastructure. It supports private registries with fine-grained IAM access control, image scanning, and lifecycle policies to automatically clean up old images.
ECR Concepts: Registry, Repository, and Image Tags
ECR organizes container images in a hierarchy. Understanding the structure helps with access control design and cross-account usage.
| Concept | Description | Example |
|---|---|---|
| Registry | One private registry per AWS account per region | 123456789.dkr.ecr.us-east-1.amazonaws.com |
| Repository | Stores images for a single application | 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app |
| Image | Specific container image - identified by tag or digest | my-app:1.2.3 or my-app@sha256:abc... |
| Tag | Mutable label pointing to an image digest | latest, v1.2.3, git-abc123 |
| Digest | Immutable SHA256 hash of the image manifest | sha256:a1b2c3... |
| Public ECR Gallery | Public registry at public.ecr.aws | public.ecr.aws/amazonlinux/amazonlinux |
Never rely on the "latest" tag in production. Tags are mutable and can be overwritten. Always pin images by digest (sha256:...) in production manifests or use immutable tag settings on the repository to prevent overwrites.
Authentication, Access Control, and Cross-Account Access
ECR uses IAM for authentication. You must retrieve a temporary token before pushing or pulling. The token is valid for 12 hours.
# Authenticate Docker to ECR (token valid 12 hours)
aws ecr get-login-password --region us-east-1 | \
docker login \
--username AWS \
--password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Push an image
docker tag my-app:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
# Create a new repository
aws ecr create-repository \
--repository-name my-app \
--image-scanning-configuration scanOnPush=true \
--image-tag-mutability IMMUTABLECross-account access uses ECR repository policies (resource-based policies) similar to S3 bucket policies. This is required when your CI/CD account pushes images that production accounts pull.
| Access Pattern | Mechanism | Example |
|---|---|---|
| Same-account pull (ECS/EKS) | Task execution role with ECR pull permissions | ecr:GetDownloadUrlForLayer, ecr:BatchGetImage |
| Cross-account pull | Repository policy granting another account access | Add Principal: account B ARN to repository policy |
| CI/CD push | IAM user/role with ECR push permissions | ecr:PutImage, ecr:InitiateLayerUpload, ecr:UploadLayerPart |
| Public ECR pull | No authentication needed for public repos | Free anonymous pull from public.ecr.aws |
For ECS and EKS, the task execution role or node IAM role needs AmazonEC2ContainerRegistryReadOnly. For cross-account, add a resource-based policy to each ECR repository. Consider using ECR pull-through cache to centralize cross-account access.
Image Scanning: Basic and Enhanced (Inspector)
ECR provides two levels of vulnerability scanning. Enhanced scanning uses Amazon Inspector for deeper analysis.
| Feature | Basic Scanning | Enhanced Scanning (Inspector) |
|---|---|---|
| Engine | Open-source Clair | Amazon Inspector + Snyk |
| Trigger | On push or manual | Continuous - rescans as new CVEs emerge |
| Layers scanned | OS packages only | OS + application packages (npm, pip, gem, jar) |
| Programming languages | Not supported | Python, Node.js, Java, Ruby, Go |
| Cost | Free | Amazon Inspector pricing (~$0.09/image/month) |
| Findings | ECR console only | Inspector console, Security Hub, EventBridge |
# Configure enhanced scanning on a repository
aws ecr put-registry-scanning-configuration \
--scan-type ENHANCED \
--rules "scanFrequency=CONTINUOUS_SCAN,repositoryFilters=[{filter=*,filterType=WILDCARD}]"
# Get scan results for an image
aws ecr describe-image-scan-findings \
--repository-name my-app \
--image-id imageTag=v1.2.3Use EventBridge to trigger automated responses to critical vulnerabilities - for example, sending a Slack notification or blocking deployment when a CRITICAL CVE is found in a freshly pushed image.
Lifecycle Policies for Cost Control
ECR charges $0.10/GB/month for stored images. Lifecycle policies automatically expire old images to control costs. Without them, image storage grows indefinitely.
// Lifecycle policy - keep last 30 tagged images, delete untagged after 1 day
{
"rules": [
{
"rulePriority": 1,
"description": "Remove untagged images after 1 day",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 1
},
"action": { "type": "expire" }
},
{
"rulePriority": 2,
"description": "Keep only 30 tagged images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": { "type": "expire" }
}
]
}| Rule Type | Use Case | Common Setting |
|---|---|---|
| sinceImagePushed | Delete images older than N days | Untagged: 1 day, dev branches: 7 days |
| imageCountMoreThan | Keep only N most recent images | Production tags: keep 30 |
| tagStatus: untagged | Clean up build cache layers | Always expire within 1-3 days |
| tagStatus: tagged + prefix | Manage specific tag patterns | dev-, pr-, sha- prefixes expire sooner |
Replication and Pull-Through Cache
ECR supports two features for multi-region and multi-account scenarios: cross-region/cross-account replication, and pull-through cache for upstream public registries.
| Feature | Purpose | How It Works |
|---|---|---|
| Cross-region replication | DR and low-latency pulls in other regions | ECR automatically copies images to destination regions on push |
| Cross-account replication | Central image registry shared across accounts | Push once to central account, ECR replicates to spoke accounts |
| Pull-through cache | Proxy and cache public registry images | ECR caches Docker Hub, ECR Public, Quay images in your private registry |
Pull-through cache is particularly valuable for avoiding Docker Hub rate limits (100 pulls/6hr for anonymous, 200/6hr for free accounts) in CI/CD pipelines.
# Create a pull-through cache rule for Docker Hub
aws ecr create-pull-through-cache-rule \
--ecr-repository-prefix docker-hub \
--upstream-registry-url registry-1.docker.io
# Now pull nginx via ECR pull-through cache
docker pull 123456789.dkr.ecr.us-east-1.amazonaws.com/docker-hub/library/nginx:latest
# ECR fetches from Docker Hub on first pull, caches for subsequent pullsPull-through cache repositories are created automatically on first pull. They use the same lifecycle policies as regular repositories. This is the recommended approach for mirroring public images used in EKS pods to avoid rate limiting and improve pull latency.
Interview Focus Points
- 1How do you grant an ECS task in account A permission to pull an ECR image from account B?
- 2What is the difference between image tags and image digests - why should production use digests?
- 3How do ECR lifecycle policies work and how would you design one for a CI/CD pipeline that builds 20 images per day?
- 4What is ECR pull-through cache and when would you use it?
- 5How does ECR image scanning differ between basic and enhanced modes - what does enhanced catch that basic does not?
- 6Walk me through the ECR authentication flow - how does a Kubernetes pod authenticate to pull an image?
- 7How would you set up ECR replication for a multi-region application deployment?
- 8What IAM permissions does the ECS task execution role need for ECR, and why is it separate from the task role?