DVA-C02Chapter 70 of 101Objective 3.4

Amazon ECR Container Registry

Amazon Elastic Container Registry (ECR) is a fully managed Docker container registry that stores, manages, and deploys container images. For the DVA-C02 exam, ECR is a core topic under Domain 3: Deployment, Objective 3.4: Manage container-based applications. Approximately 5-8% of exam questions involve ECR, often combined with ECS, EKS, or Lambda. This chapter covers ECR architecture, authentication, image management, lifecycle policies, cross-region replication, and security best practices. By the end, you will understand how to push, pull, and automate container image workflows in AWS, and you'll be prepared for exam scenarios that test your knowledge of ECR's integration with other services, its permission model, and common troubleshooting.

25 min read
Intermediate
Updated May 31, 2026

ECR as a Private Docker Hub Warehouse

Amazon ECR is like a private, automated warehouse for your Docker containers. Imagine you run a shipping company that uses standardized cargo containers (Docker images). You have your own secure warehouse (ECR repository) where you store these containers. The warehouse has a specific address (registry URI) and each container has a unique barcode (image tag). To store a new container, you drive a truck (Docker client) to the warehouse entrance, where a security guard (AWS IAM) checks your credentials (authentication token) and logs you in. The warehouse uses a conveyor belt (HTTPS) to move containers inside, and each container is unpacked into its own storage bin (image layers), with a manifest (image manifest) listing all the bins. When you need a container for a delivery (deployment), you send a request with the barcode. The warehouse retrieves the bins, reassembles the container, and hands it to your truck. The warehouse also has a replication service (cross-region replication) that automatically copies containers to another warehouse in a different city for disaster recovery. Lifecycle policies automatically remove old containers that haven't been used for a set number of days, freeing up space. The warehouse keeps a detailed log (CloudTrail) of every container stored or retrieved. This is exactly how ECR works: a private, secure, and automated registry for Docker images, integrated with IAM for access control and lifecycle management for cleanup.

How It Actually Works

What is Amazon ECR?

Amazon ECR is a fully managed Docker container registry that stores, manages, and deploys container images. It eliminates the need to operate your own registry or worry about scaling the underlying infrastructure. ECR integrates with AWS Identity and Access Management (IAM) for resource-level permissions, supports image vulnerability scanning, and offers lifecycle policies to automatically clean up unused images. It is the primary registry for Amazon ECS and EKS, and can also be used with on-premises Docker installations.

How ECR Works Internally

ECR stores images in a hierarchical structure: a registry (your AWS account) contains multiple repositories, each repository holds multiple images, and each image is composed of layers and a manifest. When you push an image via the Docker CLI, the Docker client interacts with the ECR API using HTTPS. The push process involves: 1. Authentication: Get an authorization token from ECR (the GetAuthorizationToken API) and use it to authenticate Docker to the registry. 2. Layer upload: Each layer of the image is uploaded separately via InitiateLayerUpload, UploadLayerPart, and CompleteLayerUpload calls. Layers are stored in Amazon S3 under the hood, and ECR manages the S3 buckets transparently. 3. Manifest upload: After all layers are uploaded, the image manifest (a JSON file describing the layers, tags, and configuration) is uploaded via PutImage. The manifest references the layer digests.

When pulling an image, the reverse happens: the manifest is fetched first, then each layer is downloaded individually. ECR supports both HTTPS and VPC Endpoints (AWS PrivateLink) for secure, private connectivity within a VPC.

Key Components and Defaults

Registry: The endpoint is account-id.dkr.ecr.region.amazonaws.com. Each AWS account has one registry per region.

Repository: A logical grouping of images. Repository names can contain up to 256 characters, including slashes (for namespacing, e.g., myapp/backend).

Image Tag: A mutable pointer to an image manifest. Tags can be up to 128 characters. The latest tag is commonly used but is mutable and can cause confusion.

Image Digest: An immutable SHA-256 hash of the manifest. You can always pull an image by its digest (e.g., image@sha256:abc123...).

Image Layers: Each layer is a diff of the filesystem. Layers are stored in S3 and referenced by their digest. ECR enforces a maximum of 10,000 layers per image? No, that's not a limit; but the total image size can be up to 15 GB (soft limit, can be increased).

Lifecycle Policy: A set of rules that automatically expire images based on tag status (tagged/untagged) and age (since pushed) or count (more than N images). Rules are evaluated once per day.

Scan on Push: Can be enabled to automatically scan images for vulnerabilities after they are pushed. Scans use the Common Vulnerabilities and Exposures (CVE) database from Amazon Inspector.

Cross-Region Replication: Replicates repositories and images to a destination region automatically. Replication is asynchronous and can be configured with filters (e.g., only replicate images with a specific tag prefix).

Lifecycle Policy Defaults: There is no default lifecycle policy; you must create one. A common policy is to expire untagged images older than 14 days.

Authentication Methods

To interact with ECR, you must authenticate. The recommended methods are: - AWS CLI: aws ecr get-login-password --region region | docker login --username AWS --password-stdin account-id.dkr.ecr.region.amazonaws.com - Docker credential helper: The amazon-ecr-credential-helper automatically handles authentication when pushing/pulling from ECR. - IAM roles: For EC2 instances or ECS tasks, you can attach an IAM role with permissions like ecr:GetDownloadUrlForLayer, ecr:BatchGetImage, ecr:BatchCheckLayerAvailability, ecr:GetAuthorizationToken, etc.

Permissions Model

ECR uses resource-based policies (similar to S3 bucket policies) and IAM identity-based policies. Key points: - Repository policy: Controls cross-account access. You can grant other AWS accounts access to pull/push images by attaching a policy to the repository. - IAM policy: Controls user/role access. Example actions: ecr:GetDownloadUrlForLayer, ecr:BatchGetImage, ecr:PutImage, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload. To list repositories, you need ecr:DescribeRepositories. - GetAuthorizationToken: This is a service-level permission (not repository-specific). You must allow this action on the user/role to generate tokens. - Cross-account access: The source account must attach a repository policy granting ecr:BatchGetImage and ecr:GetDownloadUrlForLayer to the target account. The target account must also have IAM permissions to pull. The target account then authenticates using its own credentials and pulls from the source account's repository URI.

Lifecycle Policies

Lifecycle policies help manage image cleanup. They consist of rules with: - rulePriority: Integer (1-1000). Lower numbers have higher priority. The first matching rule is applied. - description: Optional string. - selection: Defines which images are affected. - tagStatus: tagged, untagged, or any. - tagPrefixList: For tagged images, filter by prefix. - countType: imageCountMoreThan or sinceImagePushed. - countNumber: Number of images to retain or age in days. - countUnit: days (only for sinceImagePushed). - action: expire.

Example policy that expires untagged images older than 14 days:

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Expire untagged images older than 14 days",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 14
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

Cross-Region Replication

Replication copies images from a source repository to a destination repository in another region. To set up replication: 1. In the source region, create a replication configuration on the registry (not per-repository). 2. Specify the destination region and an optional filter (e.g., repository name prefix). 3. ECR automatically creates the destination repository (if it doesn't exist) and copies images asynchronously. 4. Replication is one-way: images pushed to the source are replicated to the destination. Changes in the destination are not replicated back. 5. Replication requires IAM permissions in both regions. The source registry must have a replication policy granting ecr:ReplicateImage to the destination.

Image Scanning

ECR can scan images for software vulnerabilities. Scanning can be triggered on push or manually. The scan results are stored in ECR and can be retrieved via the AWS Console, CLI, or API. Scanning uses the Amazon Inspector vulnerability database. Exam tip: Scanning is not real-time; it may take a few minutes after push to complete. The scan status can be PENDING, SCANNING, COMPLETE, or FAILED.

Integration with Other Services

Amazon ECS: ECS task definitions reference ECR images via the image field. ECS agents authenticate to ECR using the ECS task role (which needs ecr:GetAuthorizationToken and ecr:BatchGetImage).

Amazon EKS: Kubernetes pods can pull images from ECR. You need to configure a docker-registry secret or use IAM roles for service accounts (IRSA).

AWS Lambda: Lambda functions can use container images stored in ECR (up to 10 GB). The function's execution role must have ecr:GetDownloadUrlForLayer and ecr:BatchGetImage.

AWS CodeBuild/CodePipeline: Can build and push images to ECR. CodeBuild can use the aws ecr get-login-password command in the buildspec.

AWS CloudFormation: You can define ECR repositories as AWS::ECR::Repository resources.

CLI Commands

Common AWS CLI commands for ECR:

# Get login token
echo $(aws ecr get-login-password --region us-east-1) | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com

# Create repository
aws ecr create-repository --repository-name my-repo --region us-east-1

# List images
aws ecr list-images --repository-name my-repo

# Describe images (includes tags, digest, size)
aws ecr describe-images --repository-name my-repo

# Batch delete images
aws ecr batch-delete-image --repository-name my-repo --image-ids imageTag=old-tag

# Set lifecycle policy
aws ecr put-lifecycle-policy --repository-name my-repo --lifecycle-policy-text file://policy.json

# Start image scan
aws ecr start-image-scan --repository-name my-repo --image-id imageTag=my-tag

Limits and Defaults

Maximum number of repositories per account per region: 10,000.

Maximum number of images per repository: 10,000.

Maximum image size: 15 GB (soft limit, can be increased via support request).

Maximum layer size: 10 GB (since each layer is a separate upload).

Maximum number of tags per image: 50.

Lifecycle policy evaluation: once per day.

Scan results are stored for 30 days.

Walk-Through

1

Authenticate Docker to ECR

Before any push or pull, you must authenticate the Docker client to the ECR registry. Run `aws ecr get-login-password --region <region>` to get a temporary token (valid for 12 hours). Then pipe that token into `docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com`. The token is an authorization token that Docker passes in the HTTP Authorization header for all subsequent requests. The IAM principal executing `get-login-password` must have the `ecr:GetAuthorizationToken` permission. Without this step, Docker will receive a 403 Forbidden error.

2

Tag the local image

Before pushing, you must tag your local Docker image with the ECR repository URI. Use `docker tag <local-image> <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:<tag>`. This creates a new tag that points to the same image ID. The tag must be unique within the repository. If you omit the tag, Docker defaults to `latest`. It is a best practice to use semantic versioning or commit hashes rather than `latest` to avoid confusion. The tagging step does not involve network calls; it just adds a metadata alias locally.

3

Push the image to ECR

Run `docker push <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:<tag>`. Docker splits the image into layers and checks if each layer already exists in the repository by calling `BatchCheckLayerAvailability`. For new layers, Docker calls `InitiateLayerUpload` to get an upload ID, then uploads the layer in parts (up to 5MB each) via `UploadLayerPart`, and finally calls `CompleteLayerUpload` to assemble the layer. After all layers are uploaded, Docker calls `PutImage` to upload the manifest. The manifest is a JSON file that lists the layers and their digests. ECR verifies the manifest and stores it. If the push fails halfway, you can resume by re-uploading the missing layers.

4

Verify the image in ECR

After a successful push, verify the image exists using the AWS CLI or Console. Run `aws ecr describe-images --repository-name <repo-name>` to see the image details, including the digest (SHA256), tags, and size. You can also use `aws ecr list-images --repository-name <repo-name>` for a simpler list. The image digest is immutable — even if you push a new image with the same tag, the digest changes. You can pull the image by digest to ensure you get the exact same image. The Console shows the image URI and allows you to copy it for use in ECS or EKS.

5

Pull the image from ECR

To pull an image, run `docker pull <account-id>.dkr.ecr.<region>.amazonaws.com/<repo-name>:<tag>`. Docker first fetches the manifest using `BatchGetImage`. Then it downloads each layer using `GetDownloadUrlForLayer`, which returns a pre-signed S3 URL (valid for 1 hour) for the layer blob. Layers are downloaded in parallel and cached locally. If you pull by digest (e.g., `image@sha256:...`), Docker ensures you get the exact image. The pull requires IAM permissions: `ecr:GetDownloadUrlForLayer`, `ecr:BatchGetImage`, and `ecr:BatchCheckLayerAvailability`. For cross-account pulls, the repository policy must grant these actions to the pulling account.

What This Looks Like on the Job

Scenario 1: CI/CD Pipeline for Microservices A large e-commerce company uses Jenkins and AWS CodeBuild to build hundreds of microservices daily. Each service is containerized and pushed to ECR with a unique tag based on the Git commit hash (e.g., abc123def). They use lifecycle policies to keep only the last 10 tagged images for each service to save storage costs. Untagged images (from failed builds) are expired after 7 days. They also enable scan on push to catch vulnerabilities before deployment. The CI/CD pipeline uses IAM roles with least privilege: the build role has permissions to push to specific repositories only. They encountered an issue where the build server's Docker credential helper expired — they now refresh the token before each build. They also use cross-region replication to replicate production images to a DR region. The main challenge is managing the sheer number of images (over 50,000) and ensuring the lifecycle policy runs efficiently. They monitor repository size using CloudWatch metrics (RepositorySizeBytes) and set alarms for unexpected growth.

Scenario 2: Hybrid Deployment with On-Premises Docker A financial services firm runs a mix of workloads on AWS and on-premises. They use ECR as the single source of truth for container images. On-premises Docker hosts authenticate to ECR using IAM roles (via instance profiles on EC2) or access keys for non-AWS servers. They use VPC endpoints (AWS PrivateLink) to keep traffic within their network, avoiding public internet exposure. They also use a repository policy that restricts access to their VPC only (using aws:SourceVpce condition). A common problem is that on-premises pull requests fail due to missing internet route or expired token — they now use the amazon-ecr-credential-helper to automatically refresh tokens. They also replicate critical images to a second region for disaster recovery. Performance is generally good, but large images (>5GB) can take minutes to pull, so they optimize layer caching and use multi-stage builds.

Scenario 3: Lambda Container Images A serverless startup uses ECR to store Lambda function container images. They package each Lambda function as a container image (up to 10 GB) and push it to ECR. The Lambda execution role needs ecr:GetDownloadUrlForLayer and ecr:BatchGetImage permissions. They use image tags like v1.0.0 and also tag with latest for development. They learned the hard way that Lambda does not automatically pull the latest tag — you must update the function configuration to point to the new image. They use lifecycle policies to delete images older than 90 days. A common mistake is forgetting to update the Lambda function's image URI after pushing a new tag, causing the function to run the old code. They now use AWS CodePipeline to automatically update the Lambda function after a successful push.

How DVA-C02 Actually Tests This

The DVA-C02 exam tests ECR under Domain 3: Deployment, Objective 3.4: Manage container-based applications. You should expect 2-3 questions that combine ECR with ECS, EKS, or Lambda. The exam focuses on:

1.

Authentication and Permissions: The most common scenario is a Docker push/pull failing due to missing permissions. The exam will test that you need ecr:GetAuthorizationToken to get the token, and then ecr:PutImage, ecr:InitiateLayerUpload, etc., for push, or ecr:GetDownloadUrlForLayer for pull. A typical wrong answer is to include only ecr:* actions, which is overly permissive but not the best practice. Another trap: confusing ecr:GetAuthorizationToken with ecr:GetLoginPassword — the latter is not an IAM action; it's an API operation.

2.

Lifecycle Policies: You'll be asked to write or interpret a lifecycle policy that expires untagged images older than X days. The exam loves the tagStatus: "untagged" and countType: "sinceImagePushed" combination. A common wrong answer uses tagStatus: "any" which would also expire tagged images. Also, remember that lifecycle policies are evaluated once per day, not immediately.

3.

Cross-Region Replication: Know that replication is configured at the registry level (not per-repository), uses a replication configuration, and requires IAM permissions. A common wrong answer is that replication is automatic without any setup — it is not; you must configure it. Also, replication is one-way.

4.

Image Scanning: Scanning can be automated on push. The exam may ask what happens if you push an image and then immediately check scan results — the answer is that scanning is asynchronous and may not be complete yet. The scan status will be PENDING or SCANNING.

5.

Cross-Account Access: You need a repository policy in the source account granting ecr:BatchGetImage and ecr:GetDownloadUrlForLayer to the target account. The target account then authenticates with its own IAM credentials. A common mistake is to think the target account can use the source account's token.

6.

Integration with ECS: The ECS task execution role needs ecr:GetAuthorizationToken, ecr:BatchGetImage, and ecr:GetDownloadUrlForLayer. If the task fails to pull the image, check the task execution role permissions.

7.

Edge Cases: Tag mutability — you can push a new image with an existing tag; the old image is not deleted but loses its tag. To prevent overwriting, you can enable tag immutability on the repository. The exam might ask: "How do you prevent accidental overwrite of a production image?" Answer: Enable tag immutability.

8.

Numbers: Token expiry is 12 hours. Lifecycle policy evaluation is once per day. Image size limit is 15 GB (soft limit). Maximum repositories per account per region is 10,000.

To eliminate wrong answers, focus on the underlying mechanism: ECR uses S3 for storage, and all API calls are HTTPS. If a question mentions VPC endpoints, the correct answer involves PrivateLink and the ecr.dkr endpoint. If a question mentions scanning, remember it's asynchronous.

Key Takeaways

ECR is a regional, fully managed Docker registry; each account has one registry per region.

Authentication requires `ecr:GetAuthorizationToken`; the token is valid for 12 hours.

Push and pull require specific IAM actions: `ecr:PutImage`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`, `ecr:BatchGetImage`.

Lifecycle policies evaluate once per day and can expire images by age or count, with tag status filters.

Cross-region replication is configured at the registry level and is one-way asynchronous.

Image scanning on push is asynchronous; check scan status with `DescribeImageScanFindings`.

Tag immutability can be enabled on a repository to prevent overwriting tags.

ECR integrates with ECS, EKS, Lambda, CodeBuild, and CloudFormation.

Repository policies enable cross-account access; the target account authenticates with its own credentials.

Maximum image size is 15 GB (soft limit); maximum repositories per account per region is 10,000.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Amazon ECR

Fully managed by AWS, integrates with IAM for fine-grained access control.

Supports lifecycle policies to automatically clean up images based on age or count.

Offers image scanning for vulnerabilities using Amazon Inspector.

Can be accessed via VPC endpoints (PrivateLink) for private connectivity.

No built-in rate limiting for pulls; scales with your account limits.

Docker Hub (Public)

Public registry, open to the internet; access control via Docker Hub tokens or teams.

No built-in lifecycle management; you must manually delete images.

Image scanning is a paid feature (Docker Hub Pro/Team).

No VPC endpoint; traffic goes over the public internet.

Rate limits apply for anonymous pulls (100 pulls per 6 hours) and authenticated pulls (200 pulls per 6 hours for free tier).

Watch Out for These

Mistake

ECR is a global service; you can push to any region from anywhere.

Correct

ECR is regional. Each registry is scoped to a single region. You must use the correct region-specific endpoint (e.g., `account-id.dkr.ecr.us-east-1.amazonaws.com`). To push to multiple regions, you must push to each region separately or set up cross-region replication.

Mistake

Once an image is tagged with 'latest', it always points to the latest pushed image.

Correct

The 'latest' tag is just a mutable string. If you push a new image with the same tag, the tag moves to the new image. The old image becomes untagged but still exists. You can still pull it by its digest. Tag mutability is the default; you can enable tag immutability to prevent overwriting.

Mistake

Lifecycle policies delete images immediately after the rule matches.

Correct

Lifecycle policies are evaluated once per day (typically within 24 hours). The deletion does not happen instantly. There is no guarantee of immediate cleanup. Use the `aws ecr start-lifecycle-policy-preview` to see what would be deleted.

Mistake

You need to manage S3 buckets for ECR storage.

Correct

ECR manages the underlying S3 storage automatically. You do not have access to the S3 buckets. All interactions are through the ECR API. You cannot directly upload or download layers via S3.

Mistake

Cross-account access requires the source account to share the authorization token.

Correct

Each account authenticates independently. The source account grants repository permissions via a repository policy. The target account uses its own IAM credentials to get its own authorization token and then pulls from the source account's repository URI.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

How do I authenticate Docker to Amazon ECR?

Use the AWS CLI to get a login password: `aws ecr get-login-password --region <region>`. Then pass it to Docker: `docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com`. The token is valid for 12 hours. For automated environments, use the `amazon-ecr-credential-helper` which handles token refresh automatically. Ensure the IAM principal has the `ecr:GetAuthorizationToken` permission.

What IAM permissions are needed to push an image to ECR?

To push an image, you need at least: `ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:BatchCheckLayerAvailability`, and `ecr:PutImage`. For listing repositories, you need `ecr:DescribeRepositories`. It's a best practice to scope permissions to specific repositories using resource ARNs (e.g., `arn:aws:ecr:us-east-1:123456789012:repository/my-repo`).

How can I automatically delete old images in ECR?

Use lifecycle policies. Create a JSON policy with rules that specify `tagStatus` (e.g., `untagged`), `countType` (e.g., `sinceImagePushed`), `countNumber` (days), and `action: expire`. Attach the policy to the repository via the AWS Console, CLI (`put-lifecycle-policy`), or CloudFormation. Policies are evaluated once per day. Example: expire untagged images older than 14 days.

Can I pull images from ECR across AWS accounts?

Yes. The source account must attach a repository policy that grants `ecr:BatchGetImage` and `ecr:GetDownloadUrlForLayer` to the target account (by account ID or IAM role ARN). The target account then authenticates with its own IAM credentials and pulls using the source account's repository URI. The target account's IAM role also needs the same pull permissions.

What is the difference between an image tag and an image digest?

A tag is a mutable, human-readable string (e.g., `v1.0`, `latest`) that points to an image manifest. A digest is an immutable SHA-256 hash of the manifest (e.g., `sha256:abc123...`). Tags can be reassigned to different images; digests uniquely identify a specific image version. Always use digests in production to ensure you deploy the exact same image.

How do I set up cross-region replication for ECR?

In the source region's registry settings, create a replication configuration. Specify the destination region (e.g., `us-west-2`) and optionally a filter (e.g., repository name prefix). ECR will automatically create the destination repository if it doesn't exist and replicate images asynchronously. You need IAM permissions in both regions. Replication is one-way only.

Why is my ECS task failing to pull the image from ECR?

Common causes: (1) The ECS task execution role lacks permissions: `ecr:GetAuthorizationToken`, `ecr:BatchGetImage`, `ecr:GetDownloadUrlForLayer`. (2) The image URI is incorrect (wrong region, account ID, or repository name). (3) The image tag does not exist. (4) Network issues: if using a VPC, ensure the task can reach the ECR endpoint (either via NAT gateway or VPC endpoint). Check the task logs for specific error messages.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Amazon ECR Container Registry — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.

Done with this chapter?