AB
Learn how to use AWS Elastic Container Registry (ECR) for storing, managing and deploying Docker container images with this detailed guide covering setup, integration, and best practices.
In this blog, we will explore AWS Elastic Container Registry (ECR), a fully managed container image registry service from Amazon Web Services. We’ll cover the fundamental concepts of ECR and provide a practical, step-by-step guide to using it effectively, from setting up a repository to pushing and pulling Docker images. Let’s dive in!
AWS Elastic Container Registry (ECR) is a fully managed container image registry service provided by Amazon Web Services (AWS). It allows developers to store, manage, and deploy Docker container images securely and efficiently. ECR is designed to integrate seamlessly with other AWS services, such as Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS), making it a key service in a containerized application workflow.
By using ECR, you can easily store your Docker images and make them available for deployment to ECS or EKS clusters. ECR also ensures that your container images are highly available and can be accessed from anywhere in the world.
ECR consists of two main offerings:
AWS ECR provides several advantages that make it a go-to solution for managing Docker container images:
Security: ECR ensures your images are secure by offering encryption at rest and private repositories by default. Only authorized users can access the images, ensuring data privacy and security. ECR also integrates with AWS Identity and Access Management (IAM) for fine-grained access control.
Integration: ECR integrates smoothly with other AWS services like ECS, EKS, and AWS Fargate. This seamless integration allows you to deploy your containers with ease and manage them effectively.
Scalability: Being a fully managed service, ECR scales automatically to accommodate growing container image storage needs without manual intervention.
Availability: ECR guarantees high availability, so your images are accessible at any time without worrying about downtime during critical deployments.
Lifecycle Policies: ECR allows you to set lifecycle policies to manage your container images. These policies help in automating the cleanup of unused or old images, ensuring cost-effective storage management.
Image Scanning: ECR provides built-in vulnerability scanning to identify security issues in your container images, helping you maintain a secure environment.
Cross-Region and Cross-Account Replication: ECR supports replicating your container images across AWS regions and accounts, enhancing disaster recovery and availability.
Layman Example: Think of ECR as a cloud-based “warehouse” where you store your Docker containers (like products). You don’t need to worry about maintaining the warehouse, its security, or availability—AWS does that for you. You can set rules for automatic “restocking” (pushing new images) and “cleaning out old inventory” (lifecycle policies), and it seamlessly connects with your “delivery system” (ECS/EKS).
Let’s go over how to get started with AWS ECR.
Now you’ve got your own repository to store Docker images.
Example Repository Creation with AWS CLI:
If you prefer using the CLI, you can create a repository with the following command:
aws ecr create-repository \
--repository-name my-application \
--image-scanning-configuration scanOnPush=true \
--region us-east-1
This command creates a new repository named “my-application” with scan-on-push enabled in the us-east-1 region.
To interact with ECR from your local machine, you need the AWS CLI installed. Follow these instructions to install it:
For Windows, macOS, or Linux, you can follow the instructions in the AWS CLI User Guide.
Once installed, you can check if it’s working by running:
aws --version
This will return the version of the AWS CLI installed, confirming that it’s ready for use.
Once AWS CLI is installed, you need to configure it with your AWS credentials:
Open your terminal (or command prompt) and run:
aws configure
You’ll be prompted to enter your AWS Access Key ID, Secret Access Key, default region, and preferred output format (e.g., JSON). You can find your access keys in the AWS Management Console under IAM (Identity and Access Management).
Example Configuration:
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json
Best Practice: Instead of using your root AWS account credentials, create an IAM user with appropriate permissions and use those credentials.
After setting up your ECR repository and configuring the AWS CLI, you can push Docker images to your repository.
First, create a Docker image by running the following command in your project directory (where the Dockerfile is located):
docker build -t my-application:latest .
This command builds the Docker image with the name “my-application” and the tag “latest” using the Dockerfile in the current directory.
Example Dockerfile:
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
This is a simple Dockerfile for a Node.js application.
Once the image is built, you need to tag it with the URI of your ECR repository:
aws_account_id=$(aws sts get-caller-identity --query Account --output text)
region=$(aws configure get region)
ecr_repo_uri=$aws_account_id.dkr.ecr.$region.amazonaws.com/my-application
docker tag my-application:latest $ecr_repo_uri:latest
This script gets your AWS account ID and region automatically, then tags your image with the ECR repository URI.
To push the image, you need to authenticate Docker with ECR:
aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $aws_account_id.dkr.ecr.$region.amazonaws.com
This command retrieves a temporary password from AWS and logs in to the ECR registry.
Now that you’re logged in, you can push your image to the ECR repository:
docker push $ecr_repo_uri:latest
This command uploads the Docker image to the ECR repository, making it available for use in ECS, EKS, or other AWS services.
Example Complete Push Script:
Here’s a complete bash script for building, tagging, and pushing a Docker image to ECR:
#!/bin/bash
# Set variables
image_name="my-application"
tag="latest"
aws_account_id=$(aws sts get-caller-identity --query Account --output text)
region=$(aws configure get region)
ecr_repo_uri=$aws_account_id.dkr.ecr.$region.amazonaws.com/$image_name
# Build the image
echo "Building Docker image..."
docker build -t $image_name:$tag .
# Tag the image for ECR
echo "Tagging image for ECR..."
docker tag $image_name:$tag $ecr_repo_uri:$tag
# Login to ECR
echo "Logging in to ECR..."
aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $aws_account_id.dkr.ecr.$region.amazonaws.com
# Push to ECR
echo "Pushing image to ECR..."
docker push $ecr_repo_uri:$tag
echo "Image pushed successfully to $ecr_repo_uri:$tag"
You can save this as push-to-ecr.sh
, make it executable with chmod +x push-to-ecr.sh
, and run it when you want to update your ECR repository.
To use Docker images stored in ECR on other systems or services:
aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $aws_account_id.dkr.ecr.$region.amazonaws.com
docker pull $aws_account_id.dkr.ecr.$region.amazonaws.com/my-application:latest
This command downloads the image from ECR to your local machine, where you can then run it using Docker.
Example: Running the Pulled Image:
docker run -p 3000:3000 $aws_account_id.dkr.ecr.$region.amazonaws.com/my-application:latest
This command runs the container and maps port 3000 from the container to port 3000 on your local machine.
ECR offers built-in vulnerability scanning for your container images, helping you identify potential security issues.
You can enable scanning in two ways:
To enable Scan on Push for a new repository:
aws ecr create-repository \
--repository-name my-application \
--image-scanning-configuration scanOnPush=true \
--region us-east-1
To enable Scan on Push for an existing repository:
aws ecr put-image-scanning-configuration \
--repository-name my-application \
--image-scanning-configuration scanOnPush=true \
--region us-east-1
aws ecr start-image-scan \
--repository-name my-application \
--image-id imageTag=latest \
--region us-east-1
To view scan results for an image:
aws ecr describe-image-scan-findings \
--repository-name my-application \
--image-id imageTag=latest \
--region us-east-1
This returns a list of vulnerabilities found in the image, including severity levels and possible remediation steps.
Lifecycle policies help you manage the lifecycle of images in your ECR repositories, automating the cleanup of unused or old images.
Here’s an example of a lifecycle policy that keeps only the 10 most recent images and deletes images older than 90 days:
{
"rules": [
{
"rulePriority": 1,
"description": "Keep only 10 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Expire images older than 90 days",
"selection": {
"tagStatus": "any",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 90
},
"action": {
"type": "expire"
}
}
]
}
Save this JSON to a file named lifecycle-policy.json
, then apply it to your repository:
aws ecr put-lifecycle-policy \
--repository-name my-application \
--lifecycle-policy-text file://lifecycle-policy.json \
--region us-east-1
To view the lifecycle policy for a repository:
aws ecr get-lifecycle-policy \
--repository-name my-application \
--region us-east-1
You can test how a lifecycle policy would affect your repository without actually deleting any images:
aws ecr get-lifecycle-policy-preview \
--repository-name my-application \
--region us-east-1
ECR is designed to work seamlessly with other AWS services. Let’s see how it integrates with some key services:
{
"family": "my-application",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "my-application",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:latest",
"essential": true,
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000
}
]
}
],
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512"
}
Save this to task-definition.json
and register it:
aws ecs register-task-definition --cli-input-json file://task-definition.json
aws ecs create-service \
--cluster my-cluster \
--service-name my-application-service \
--task-definition my-application:1 \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678],assignPublicIp=ENABLED}"
To use ECR images with Amazon EKS, you need to configure your Kubernetes deployment to pull from ECR.
Create an IAM role for your EKS nodes with permissions to pull from ECR.
Create a Kubernetes deployment manifest that references your ECR image:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-application
spec:
replicas: 2
selector:
matchLabels:
app: my-application
template:
metadata:
labels:
app: my-application
spec:
containers:
- name: my-application
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:latest
ports:
- containerPort: 3000
Save this to deployment.yaml
and apply it:
kubectl apply -f deployment.yaml
With AWS Lambda container image support, you can use ECR images as the deployment package for your Lambda functions.
aws lambda create-function \
--function-name my-lambda-function \
--package-type Image \
--code ImageUri=123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:latest \
--role arn:aws:iam::123456789012:role/lambda-ex
Following are some best practices to make the most of AWS ECR:
Here are some common issues you might encounter when working with ECR and how to resolve them:
Issue: Error response from daemon: Get "https://123456789012.dkr.ecr.us-east-1.amazonaws.com/v2/": unauthorized: authentication required
Solution:
aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $aws_account_id.dkr.ecr.$region.amazonaws.com
Issue: An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User is not authorized to perform: ecr:GetAuthorizationToken
Solution:
AmazonECR-FullAccess
policy or a custom policy with the required permissions.Issue: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Solution:
Issue: Error response from daemon: manifest for 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application:latest not found: manifest unknown
Solution:
Understanding ECR pricing helps you optimize costs:
Cost Optimization Tips:
When you’re done using resources, it’s important to clean up to avoid unnecessary costs.
To delete specific images:
aws ecr batch-delete-image \
--repository-name my-application \
--image-ids imageTag=latest \
--region us-east-1
To delete a repository:
aws ecr delete-repository \
--repository-name my-application \
--force \
--region us-east-1
The --force
flag allows you to delete the repository even if it contains images.
By cleaning up resources, you ensure that your AWS account remains cost-effective and free of unused data.
AWS ECR is an essential service for developers using containers. It provides a secure, scalable, and highly available solution for storing and managing Docker images. In this blog, we covered how to create an ECR repository, push and pull Docker images, implement security and lifecycle policies, and integrate with other AWS services.
ECR’s seamless integration with AWS services like ECS, EKS, and Lambda makes it a cornerstone for containerized applications in the AWS ecosystem. By following the best practices and leveraging the features covered in this guide, you can ensure that your container images are securely stored, efficiently managed, and readily available for deployment.
With the steps provided, you’re now ready to integrate ECR into your containerized application workflow and streamline the deployment of your containers on AWS services.