Skip to main content
TWYTech World by Yashrajsinh

AWS ECR Container Registry

Y
Yashrajsinh
··16 min read·Beginner

AWS ECR Container Registry

Amazon Elastic Container Registry, known as ECR, is a fully managed container image registry service provided by AWS. It stores, manages, and deploys Docker container images and Open Container Initiative compatible artifacts, giving your development teams a secure and scalable place to push and pull images without operating your own registry infrastructure. Whether you are running containers on ECS, EKS, Lambda, or even on-premises Docker hosts, ECR provides the private registry that integrates natively with AWS identity, networking, and compute services.

Container registries are a critical piece of any containerized application architecture. Every time you build a Docker image, you need somewhere reliable to store it so that your deployment pipelines, orchestrators, and development environments can pull the exact version they need. Public registries like Docker Hub work for open-source images, but production workloads demand private registries with fine-grained access control, vulnerability scanning, image signing, and lifecycle management. ECR delivers all of these capabilities as a managed service, eliminating the operational burden of running and scaling a registry yourself.

This guide covers everything from creating your first repository to implementing production-grade lifecycle policies, automated vulnerability scanning, cross-account image sharing, and integration with container orchestration services. If you are following the AWS services roadmap, ECR is essential to understand before deploying containerized workloads on ECS. You should also be comfortable with Docker basics including building images, writing Dockerfiles, and understanding image layers before diving into ECR-specific concepts.

What You Will Learn

After completing this guide, you will have a comprehensive understanding of ECR and how to use it effectively in production container workflows. Specifically, you will learn:

  • How ECR repositories work at a fundamental level, including the relationship between registries, repositories, images, and tags that define the storage hierarchy
  • How to create and configure repositories using the AWS CLI, including setting image tag mutability, encryption options, and repository policies for access control
  • How to authenticate Docker to ECR and push and pull images using standard Docker commands combined with the AWS credential helper
  • How lifecycle policies automatically clean up old or untagged images to control storage costs and keep repositories manageable over time
  • How image scanning detects known vulnerabilities in your container images, both on push and on demand, using the integrated scanning engines
  • How cross-account access patterns let multiple AWS accounts share images through repository policies and IAM permissions without duplicating images across registries
  • How replication rules copy images across regions and accounts automatically for disaster recovery and multi-region deployment architectures
  • How ECR integrates with ECS task definitions, EKS pod specifications, and CI/CD pipelines to provide seamless image delivery to your container workloads
  • How to implement security best practices including image signing, pull-through cache rules, and least-privilege repository policies that protect your supply chain

Each section builds progressively, so reading from start to finish gives you the most complete understanding of how ECR fits into containerized application architectures.

Prerequisites

Before working through this guide, ensure you have the following ready:

  • An active AWS account with permissions to create ECR repositories, push and pull images, and manage lifecycle policies, either through an administrator IAM user or through a role with the appropriate ECR policies attached
  • The AWS CLI version 2 installed and configured with valid credentials using aws configure, so you can execute ECR commands directly from your terminal
  • Docker Desktop or Docker Engine installed and running on your local machine, since you will build images locally and push them to ECR using standard Docker commands
  • Familiarity with Docker basics including writing Dockerfiles, building images with docker build, understanding image layers and tags, and running containers from images
  • A basic understanding of IAM policies and roles, since ECR access control relies heavily on IAM permissions and resource-based policies to determine who can push, pull, and manage images
  • An understanding of container orchestration concepts is helpful but not required, as we cover ECS integration patterns that assume you know what task definitions and services are

No prior ECR experience is required. If you have used Docker Hub or any other container registry, the concepts of repositories, tags, and image manifests will be familiar, though ECR adds AWS-specific capabilities around IAM integration, lifecycle automation, and cross-account sharing that do not exist in simpler registries.

Concept Overview

ECR organizes container images in a hierarchical structure that mirrors how Docker registries work but adds AWS-specific management capabilities on top. Understanding this hierarchy is essential before you start creating repositories and pushing images.

At the top level, every AWS account has a default private registry in each region. The registry URL follows the pattern <account-id>.dkr.ecr.<region>.amazonaws.com. This registry is created automatically and cannot be deleted. It serves as the namespace under which all your repositories live. You do not pay for the registry itself, only for the images stored within its repositories.

Repositories live inside the registry and serve as logical groupings for related images. Each repository holds multiple versions of a single application or component, identified by tags or digest hashes. For example, you might have a repository called my-api that contains tagged images like my-api:latest, my-api:v1.2.3, and my-api:abc123 where the last tag is a Git commit hash. Repository names can include forward slashes to create a namespace hierarchy like team-a/my-api or production/backend/auth-service.

Images within a repository are identified by two mechanisms. Tags are human-readable labels like latest, v2.0.0, or staging that point to a specific image manifest. Digests are immutable SHA-256 hashes that uniquely identify an image regardless of what tags point to it. Tags can be moved to point to different images over time, which is why digest-based references are preferred for production deployments where reproducibility matters.

Image manifests describe the layers that compose an image. When you push an image to ECR, Docker uploads each layer individually and then uploads the manifest that references those layers. ECR deduplicates layers across images within the same repository, so if ten images share the same base layer, that layer is stored only once. This deduplication significantly reduces storage costs for organizations that build many images from common base images.

ECR supports both private and public repositories. Private repositories require authentication and are accessible only to principals with explicit IAM permissions. Public repositories in the ECR Public Gallery are accessible to anyone without authentication, similar to Docker Hub, and are useful for open-source projects or shared base images. This guide focuses primarily on private repositories since they are what production workloads use.

The pricing model charges for storage consumed by image data and for data transfer when pulling images. Storage costs are based on the total compressed size of all image layers in your repositories. Pulling images from ECR to services within the same region incurs no data transfer charges, which is one of the key advantages of using ECR over external registries when your compute runs in AWS.

Step-by-Step Explanation

This section walks through the essential implementation steps in order. Each step builds on the previous one, providing a clear path from initial configuration to a production-ready setup that follows AWS best practices.

Creating Your First ECR Repository

Creating a repository is the first step before you can push any images. The following commands demonstrate creating a repository with recommended production settings including image tag immutability and encryption.

# Create a private repository with tag immutability enabled
aws ecr create-repository \
  --repository-name my-application \
  --image-tag-mutability IMMUTABLE \
  --image-scanning-configuration scanOnPush=true \
  --encryption-configuration encryptionType=AES256 \
  --tags Key=Team,Value=backend Key=Environment,Value=production
 
# Verify the repository was created
aws ecr describe-repositories \
  --repository-names my-application \
  --query 'repositories[0].{Name:repositoryName,URI:repositoryUri,Scanning:imageScanningConfiguration.scanOnPush}'
 
# Get the registry login command and authenticate Docker
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com
 
# Build your Docker image locally
docker build -t my-application:v1.0.0 .
 
# Tag the image for ECR
docker tag my-application:v1.0.0 \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:v1.0.0
 
# Push the image to ECR
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:v1.0.0
 
# Verify the image exists in the repository
aws ecr describe-images \
  --repository-name my-application \
  --query 'imageDetails[].{Tags:imageTags,Pushed:imagePushedAt,Size:imageSizeInBytes}'
 
# Pull the image back (useful for verifying or deploying elsewhere)
docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:v1.0.0

The --image-tag-mutability IMMUTABLE setting prevents existing tags from being overwritten. Once you push v1.0.0, no one can push a different image with the same tag. This is critical for production environments where you need to guarantee that a specific tag always refers to the same image content. Without immutability, someone could push a completely different image as v1.0.0 and break deployments that reference that tag.

The scanOnPush=true setting triggers an automated vulnerability scan every time a new image is pushed to the repository. This ensures you always have up-to-date security information about your images without requiring manual intervention or separate scanning pipelines.

Authentication and Credential Management

ECR authentication uses temporary tokens that expire after twelve hours. The get-login-password command retrieves a token that Docker uses to authenticate push and pull operations. For automated pipelines, you need to refresh this token before it expires.

For CI/CD pipelines and developer workstations that frequently interact with ECR, the Amazon ECR Credential Helper eliminates the need to manually run login commands. Once installed and configured in your Docker configuration file, it automatically retrieves fresh credentials whenever Docker needs to authenticate with ECR. This is the recommended approach for any environment that regularly pushes or pulls images.

The credential helper works by intercepting Docker authentication requests and using the AWS SDK credential chain to obtain ECR tokens transparently. It supports all the standard AWS credential sources including environment variables, shared credential files, IAM instance profiles, and ECS task roles, making it work seamlessly across development machines, EC2 instances, and container environments.

Implementing Lifecycle Policies

Lifecycle policies automate the cleanup of old images that are no longer needed. Without lifecycle policies, repositories accumulate images indefinitely, increasing storage costs and making it harder to find relevant images. A well-designed lifecycle policy keeps your repositories lean while preserving images that are still in use or needed for rollback.

# Create a lifecycle policy that keeps only the last 30 tagged images
# and removes untagged images older than 7 days
aws ecr put-lifecycle-policy \
  --repository-name my-application \
  --lifecycle-policy-text '{
    "rules": [
      {
        "rulePriority": 1,
        "description": "Remove untagged images older than 7 days",
        "selection": {
          "tagStatus": "untagged",
          "countType": "sinceImagePushed",
          "countUnit": "days",
          "countNumber": 7
        },
        "action": {
          "type": "expire"
        }
      },
      {
        "rulePriority": 2,
        "description": "Keep only the last 30 tagged images",
        "selection": {
          "tagStatus": "tagged",
          "tagPrefixList": ["v"],
          "countType": "imageCountMoreThan",
          "countNumber": 30
        },
        "action": {
          "type": "expire"
        }
      },
      {
        "rulePriority": 3,
        "description": "Remove dev images older than 14 days",
        "selection": {
          "tagStatus": "tagged",
          "tagPrefixList": ["dev-", "feature-"],
          "countType": "sinceImagePushed",
          "countUnit": "days",
          "countNumber": 14
        },
        "action": {
          "type": "expire"
        }
      }
    ]
  }'
 
# Preview what the lifecycle policy would delete without actually deleting
aws ecr get-lifecycle-policy-preview \
  --repository-name my-application
 
# View the current lifecycle policy
aws ecr get-lifecycle-policy \
  --repository-name my-application

Lifecycle policy rules are evaluated by priority number, with lower numbers taking precedence. Each rule specifies a selection criteria that identifies which images to target and an action to take on matching images. The selection can filter by tag status (tagged, untagged, or any), tag prefix patterns, image age, or image count.

A common production pattern uses three rules: remove untagged images after a short period since they are usually failed builds, keep a fixed number of recent release images for rollback capability, and aggressively expire development and feature branch images that are only needed temporarily. This approach typically reduces storage costs by sixty to eighty percent compared to repositories without lifecycle policies.

The preview feature lets you test your policy against the current repository contents without actually deleting anything. Always run a preview before applying a new lifecycle policy to production repositories to verify it will not accidentally remove images that are still referenced by running services.

Image Scanning and Vulnerability Detection

ECR provides two scanning modes for detecting vulnerabilities in your container images. Basic scanning uses the open-source Clair engine to check for known CVEs in operating system packages. Enhanced scanning uses Amazon Inspector to provide deeper analysis including application-level dependency scanning for languages like Java, Python, Node.js, and Go.

Basic scanning runs automatically on push when configured and can also be triggered manually for existing images. It produces a findings report that lists each detected vulnerability with its severity, CVE identifier, affected package, and available fix version. The scan results are accessible through the AWS CLI, console, and EventBridge for automated alerting.

Enhanced scanning provides continuous monitoring rather than point-in-time scans. Once enabled, Inspector continuously re-evaluates your images as new vulnerabilities are disclosed, so you receive alerts about newly discovered issues in images that were previously clean. This is particularly valuable for long-lived images that may sit in your registry for weeks or months between deployments.

# Trigger a manual scan on an existing image
aws ecr start-image-scan \
  --repository-name my-application \
  --image-id imageTag=v1.0.0
 
# Check scan findings for a specific image
aws ecr describe-image-scan-findings \
  --repository-name my-application \
  --image-id imageTag=v1.0.0 \
  --query 'imageScanFindings.{Status:imageScanStatus.status,Critical:findingSeverityCounts.CRITICAL,High:findingSeverityCounts.HIGH,Medium:findingSeverityCounts.MEDIUM}'
 
# Enable enhanced scanning at the registry level
aws ecr put-registry-scanning-configuration \
  --scan-type ENHANCED \
  --rules '[{"scanFrequency":"CONTINUOUS_SCAN","repositoryFilters":[{"filter":"*","filterType":"WILDCARD"}]}]'
 
# List all images with critical vulnerabilities across repositories
aws ecr describe-image-scan-findings \
  --repository-name my-application \
  --image-id imageTag=v1.0.0 \
  --query 'imageScanFindings.findings[?severity==`CRITICAL`].{CVE:name,Package:attributes[?key==`package_name`].value|[0],Fix:attributes[?key==`package_version`].value|[0]}'

Integrating scan results into your CI/CD pipeline creates a security gate that prevents deploying images with critical vulnerabilities. After pushing an image, your pipeline waits for the scan to complete, checks the findings, and fails the deployment if critical or high-severity vulnerabilities are detected. This shift-left approach catches security issues before they reach production rather than discovering them through periodic audits.

Cross-Account Access and Image Sharing

Organizations with multiple AWS accounts often need to share container images between accounts. A development account builds and pushes images, while staging and production accounts pull those images for deployment. ECR supports this through repository policies that grant cross-account access without requiring image duplication.

Repository policies are resource-based policies attached to individual repositories that define which AWS principals can perform which actions. They work alongside IAM policies to determine effective permissions. A principal needs both an IAM policy that allows the ECR action and a repository policy that permits access from their account.

# Set a repository policy allowing another account to pull images
aws ecr set-repository-policy \
  --repository-name my-application \
  --policy-text '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "AllowCrossAccountPull",
        "Effect": "Allow",
        "Principal": {
          "AWS": [
            "arn:aws:iam::987654321098:root",
            "arn:aws:iam::111222333444:root"
          ]
        },
        "Action": [
          "ecr:GetDownloadUrlForLayer",
          "ecr:BatchGetImage",
          "ecr:BatchCheckLayerAvailability"
        ]
      }
    ]
  }'
 
# Configure replication to copy images to another region automatically
aws ecr put-replication-configuration \
  --replication-configuration '{
    "rules": [
      {
        "destinations": [
          {
            "region": "eu-west-1",
            "registryId": "123456789012"
          },
          {
            "region": "us-east-1",
            "registryId": "987654321098"
          }
        ],
        "repositoryFilters": [
          {
            "filter": "production/",
            "filterType": "PREFIX_MATCH"
          }
        ]
      }
    ]
  }'
 
# Verify replication status
aws ecr describe-registry \
  --query 'replicationConfiguration.rules[].{Destinations:destinations[].region,Filters:repositoryFilters[].filter}'

Replication rules provide an alternative to cross-account policies when you need images physically present in multiple regions or accounts. Unlike cross-account pull which requires network connectivity to the source registry at deployment time, replication copies images proactively so they are available locally even if the source region experiences issues. This is essential for disaster recovery architectures and multi-region deployments where you cannot tolerate a dependency on a single region for image availability.

Pull-Through Cache Rules

Pull-through cache rules let ECR act as a caching proxy for upstream public registries like Docker Hub, GitHub Container Registry, and Quay. When a service requests an image that matches a cache rule, ECR checks if it has a cached copy. If not, it pulls the image from the upstream registry, caches it locally, and serves it to the requester. Subsequent pulls come from the local cache without hitting the upstream registry.

This feature solves several problems. It eliminates Docker Hub rate limiting issues that affect organizations pulling many public images. It provides a local copy of critical base images that remains available even if the upstream registry experiences an outage. And it brings public images under your ECR lifecycle policies and scanning rules, giving you visibility into vulnerabilities in third-party images you depend on.

Real-World Use Cases

ECR serves as the image registry for containerized applications across a wide range of deployment patterns. Understanding common architectures helps you design solutions that leverage ECR capabilities effectively.

Microservice deployments on ECS use ECR as the source for all task definition image references. Each microservice has its own ECR repository, and the CI/CD pipeline pushes new images after successful builds and tests. ECS task definitions reference images by their full ECR URI including a specific tag or digest, and the ECS agent pulls images directly from ECR using the task execution role for authentication. This tight integration means no additional credential management is needed between ECS and ECR within the same account.

Multi-environment promotion pipelines use ECR tag conventions to track images through development, staging, and production. A common pattern tags images with both the Git commit hash for traceability and an environment label that gets updated as the image is promoted. The image my-api:abc123 gets an additional tag my-api:staging when deployed to staging, and my-api:production when promoted to production. Immutable tags on the commit hash ensure the underlying image never changes, while mutable environment tags on a separate repository track the current deployment state.

Shared base image libraries use ECR repositories with cross-account policies to distribute approved base images across an organization. A platform team maintains hardened, scanned, and approved base images in a central account. Development teams across the organization pull these base images when building their application images, ensuring everyone starts from a secure and consistent foundation. Lifecycle policies on the central repository ensure old base image versions are eventually cleaned up while giving teams time to migrate.

Serverless container deployments on AWS Lambda use ECR to store container images up to ten gigabytes in size. Lambda pulls the image from ECR when creating new execution environments, and caches layers locally for subsequent invocations. This pattern lets you package Lambda functions with large dependencies, custom runtimes, or machine learning models that exceed the traditional deployment package size limits.

Best Practices

Following established best practices for ECR ensures your container image management is secure, cost-effective, and operationally sound. These recommendations come from production experience across organizations running thousands of containers.

Enable image tag immutability on all production repositories. Mutable tags create a dangerous situation where the image behind a tag can change without any deployment action, leading to inconsistent behavior across instances that pull the same tag at different times. Immutable tags guarantee that v1.2.3 always means the same image, making deployments reproducible and rollbacks reliable.

Always enable scan-on-push for every repository. Discovering vulnerabilities at push time gives you the earliest possible warning and integrates naturally with CI/CD pipelines that can gate deployments on scan results. Combine this with enhanced scanning for continuous monitoring of images that remain in your registry between deployments.

Implement lifecycle policies on every repository from creation. Storage costs accumulate silently as repositories grow with each build. A repository receiving daily builds accumulates over three hundred images per year, most of which are never referenced again after the next build succeeds. Lifecycle policies prevent this unbounded growth automatically.

Use digest-based image references in production task definitions and pod specifications rather than tags. A digest like sha256:abc123... is immutable and globally unique, guaranteeing that every instance of your service runs exactly the same image. Tags can be moved or overwritten in repositories without immutability, creating subtle inconsistencies that are difficult to debug.

Structure repository names with a clear namespace hierarchy that reflects your organization. Patterns like <team>/<service> or <environment>/<service> make it easy to apply IAM policies, lifecycle rules, and replication configurations at the namespace level using wildcard patterns rather than managing each repository individually.

Encrypt repositories using customer-managed KMS keys when compliance requirements demand key rotation control or cross-account key sharing. The default AES-256 encryption is sufficient for most workloads, but KMS keys give you audit trails through CloudTrail and the ability to revoke access by disabling the key.

Set up EventBridge rules to alert on scan findings with critical or high severity. Automated alerts ensure your security team is notified immediately when a vulnerable image is pushed, rather than discovering issues during periodic reviews. Route these alerts to your incident management system for tracking and resolution.

Common Mistakes

Even experienced container engineers make mistakes with ECR that lead to security gaps, unexpected costs, or deployment failures. Recognizing these patterns helps you avoid them in your own container workflows.

Using mutable tags in production deployments is the most dangerous ECR mistake. When multiple ECS tasks or Kubernetes pods reference my-api:latest and someone pushes a new image with that tag, new instances pull the updated image while existing instances continue running the old one. This creates an inconsistent fleet that is extremely difficult to debug. Always use immutable tags or digests for production references.

Forgetting to configure lifecycle policies leads to unbounded storage growth. A repository receiving multiple builds per day from an active CI/CD pipeline can accumulate gigabytes of unused images within months. Since ECR charges per gigabyte-month of storage, this translates directly to wasted spending. Apply lifecycle policies at repository creation time, not as an afterthought.

Not refreshing ECR authentication tokens in long-running CI/CD pipelines causes push and pull failures. The token from get-login-password expires after twelve hours. Pipelines that cache the token across builds or run for extended periods will eventually fail with authentication errors. Use the credential helper for automated environments or refresh the token at the start of every pipeline run.

Granting overly broad repository policies that allow entire accounts to push images creates a supply chain risk. If any principal in the allowed account is compromised, they can push malicious images to your repository. Restrict push permissions to specific IAM roles used by your CI/CD pipeline, and grant only pull permissions to deployment roles.

Not using pull-through cache rules for public images means your builds depend on external registry availability. Docker Hub outages and rate limits have caused widespread build failures across the industry. Caching critical base images through ECR pull-through rules insulates your builds from upstream availability issues and rate limiting.

Ignoring scan findings because they seem overwhelming is a common reaction when first enabling scanning on repositories with many images. Instead of ignoring all findings, establish a policy that blocks deployment of images with critical vulnerabilities and tracks high-severity findings for remediation within a defined timeframe. Start with critical-only gates and expand as your team builds remediation capacity.

Storing secrets and credentials in container images rather than injecting them at runtime through environment variables or secrets managers means those secrets are permanently embedded in every layer of the image. Anyone with pull access to the repository can extract those secrets. Use AWS Secrets Manager or Parameter Store to inject sensitive values at container startup, never at build time.

Summary

ECR is the managed container registry service in AWS that provides secure, scalable storage for your Docker images with deep integration into the AWS ecosystem. You learned how registries, repositories, images, and tags form the storage hierarchy, and how to create repositories with production-ready settings including immutability and scan-on-push using the AWS CLI.

Lifecycle policies automate image cleanup based on age, count, and tag patterns, keeping your repositories lean and your storage costs controlled. Image scanning through both basic and enhanced modes detects known vulnerabilities in your images, enabling security gates in your CI/CD pipelines that prevent deploying compromised containers.

Cross-account access through repository policies and replication rules enables multi-account architectures where images flow from build accounts to deployment accounts without duplication or manual copying. Pull-through cache rules protect your builds from upstream registry outages and rate limits by caching public images locally in ECR.

The integration between ECR and AWS compute services like ECS is seamless, with task execution roles providing automatic authentication and same-region pulls incurring no data transfer charges. This native integration eliminates the credential management complexity that comes with using external registries for AWS-hosted container workloads.

As you continue building containerized applications on AWS, ECR serves as the foundation of your image supply chain. Combined with proper lifecycle policies, vulnerability scanning, and least-privilege access controls, it provides the secure and reliable image storage that production container architectures demand. Return to the AWS services roadmap to continue exploring the services that complement ECR in container deployment workflows.

Intermediate13 min read

AWS API Gateway Deep Dive

Master AWS API Gateway covering REST APIs, HTTP APIs, WebSocket, Lambda integration, authorization strategies, throttling, and production deployment.

Intermediate17 min read

AWS CloudFront CDN Guide

Master AWS CloudFront CDN distributions, origins, cache behaviors, SSL certificates, edge functions, and global content delivery best practices.

Intermediate15 min read

AWS CloudWatch Monitoring

Master AWS CloudWatch metrics, logs, alarms, dashboards, anomaly detection, and insights to build comprehensive observability for your cloud infrastructure.