Skip to content

How to Push Docker Images to AWS ECR

Docker images are usually stored on Docker Hub, but AWS’s Elastic Container Registry can also be used. It’s a great solution and this post teaches you how to push Docker images to AWS’ Elastic Container Registry (ECR).

Create a Repository

Let’s start by using the aws-cli to create a repository.

aws ecr create-repository --repository-name myname
Code language: Bash (bash)

This command successfully creates a repository and outputs the following JSON:

{ "repository": { "repositoryArn": "arn:aws:ecr:eu-west-1:098765432123:repository/myname", "registryId": "098765432123", "repositoryName": "myname", "repositoryUri": "", "createdAt": 1543162198.0 } }
Code language: JSON / JSON with Comments (json)

It’s good to also point out that additionally, running a life-cycle policy to clean up older versions will save yourself a ton of time down the line. You can run it here as follows. It’s useful so that you don’t get blocked from pushing a new version in a bit.

aws ecr put-lifecycle-policy --registry-id 098765432123 --repository-name myname --lifecycle-policy-text '{"rules":[{"rulePriority":10,"description":"Expire older images","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":100},"action":{"type":"expire"}}]}'
Code language: Bash (bash)

There are various other ways to clean up, such as by age. For now, though, we will clean up once there are 100 images in the repo.

Pushing and Pulling Images Locally

Start by authenticating your local Docker daemon against the ECR registry.

aws ecr get-login --registry-ids 098765432123 --no-include-email
Code language: Bash (bash)

This outputs a docker login and adds a new user-password pair for the Docker configuration. Copy-paste it, or run it like this instead:

$(aws ecr get-login --registry-ids 098765432123 --no-include-email)
Code language: Bash (bash)

Now pushing and pulling images is the same as what is usually done with Docker itself.

docker push docker pull
Code language: Bash (bash)

Privileges required for Pushing Images

As ECR is within AWS, you use IAM users’ permissions to get the job done. It is always recommended to only give the permissions required to achieve a particular job and nothing more.

See also  How to use Docker to test any Linux distribution locally

There are three policies that could be used for this:

  1. AmazonEC2ContainerRegistryFullAccess
  2. AmazonEC2ContainerRegistryPowerUser
  3. AmazonEC2ContainerRegistryReadOnly

You can attach these policies to an IAM user like this:

aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly --user-name andrewodendaal
Code language: Bash (bash)

You can also create your own policies, say for a CI/CD user to perform builds.

Start by creating an IAM group:

aws iam create-group --group-name myname-developers { "Group": { "Path": "/", "GroupName": "myname-developers", "GroupId": "BBB4JRDMJSHFNJSNF3ARET8KJ", "Arn": "arn:aws:iam::098765432123:group/myname-developers", "CreateDate": "2018-10-25T11:45:42Z" } }
Code language: Bash (bash)

Now add a user:

aws iam add-user-to-group --group-name myname-developers --user-name andrewodendaal
Code language: Bash (bash)

This is what will be output:

{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:DescribeRepositories", "ecr:ListImages", "ecr:DescribeImages", "ecr:BatchGetImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", "ecr:PutImage" ], "Resource": "arn:aws:ecr:eu-west-1:098765432123:repository/myname" }] }
Code language: JSON / JSON with Comments (json)

To create the policy, build out the following JSON and run a create-policy with it:

aws iam create-policy --policy-name EcrPushPullMynameDevelopers --policy-document file://./policy.json { "Policy": { "PolicyName": "EcrPushPullMynameDevelopers", "PolicyId": "ANPAITNBFTFWZMI4WFOY6", "Arn": "arn:aws:iam::098765432123:policy/EcrPushPullMynameDevelopers", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "CreateDate": "2018-10-25T12:00:15Z", "UpdateDate": "2018-10-25T12:00:15Z" } }
Code language: Bash (bash)

Then finally attach it:

aws iam attach-group-policy --group-name myname-developers --policy-arn arn:aws:iam::098765432123:policy/EcrPushPullMynameDevelopers
Code language: Bash (bash)

Use ECR images in Kubernetes

When we attached the IAM policy AmazonEC2ContainerRegistryReadOnly, it made every image available to every AWS account in the cluster.

To use it properly though, you should set the image field of the pod template on your manifest to point to it:

Code language: HTTP (http)

Tagging images

All Docker images push to a registry needs to be identified by a tag. This should be any alphanumeric value.

See also  [Solved] Terraform Error accessing remote module registry in PowerShell

It’s always good practice to add semantic versioning into tags.

MAJOR.MINOR.PATCH, such as 1.0.2.

Notify of
1 Comment
Oldest Most Voted
Inline Feedbacks
View all comments

[…] Learn how to push Docker Images to AWS Elastic Container Registry (ECR) instead of pushing them to Docker Hub in this in depth tutorial. Read more […]

Would love your thoughts, please comment.x