Ravindra BagaleCourses & study guides मराठी

Chapter 48: Docker Images: Layers, Tags, Registries, Docker Hub, ECR, Multi-Arch and Every Image Command

48.4 Push to Amazon ECR

Chala mitrano! Companies keep images not on Docker Hub but in AWS ECR. Today: create a repository, log in, push, pull, scan, immutable tags, lifecycle policy, and pull on EC2 with an IAM role, all in order.

1. Start from a company locker

Docker Hub is like a public library: easy, but outside your company. A bank like Kotak or a broker like Zerodha wants images in its own locker, inside its own AWS account, where only its own staff and servers can open it.

Amazon ECR, Elastic Container Registry, is that locker. It is a private registry in your AWS account. Access is controlled by IAM, the same permission system that controls EC2 and S3. It can scan images for known security bugs and stop anyone from overwriting a release tag.

You need the AWS CLI version 2, an AWS account and a user or role allowed to use ECR. We use region ap-south-1 (Mumbai) and the sample account 111122223333.

aws ecr create-repositorya home for the imageget-login-password12-hour tokendocker tag and pushfull ECR nameEC2, ECS, EKS pullwith an IAM role
Picture 1: the ECR flow

How is ECR different from Docker Hub? First, the images stay inside your AWS account and region, so servers in the same region pull fast and the traffic stays on the AWS network. Second, there are no passwords to share: people and servers get access through IAM users and roles, and you can remove that access in one click. Third, ECR can scan images and expire old ones by itself.

The price is small: you pay for the storage your images use and for data that leaves the region. A team with a few services usually pays a few dollars a month. Keep that in mind when we set a lifecycle policy at the end.

2. Set up

Step 1: Check the AWS CLI and who you are

Why: Most ECR errors are really AWS login errors.

What: aws sts get-caller-identity prints which account and user the CLI is using.

Example 1: CLI version

Type this:

aws --version

You will see:

aws-cli/2.18.5 Python/3.12.6 Linux/6.8.0 exe/x86_64.ubuntu.24

What it means: Version 2 is needed for get-login-password.

Example 2: Who am I

Type this:

aws sts get-caller-identity

You will see:

{
  "UserId": "AIDA...",
  "Account": "111122223333",
  "Arn": "arn:aws:iam::111122223333:user/ravi"
}

What it means: Right account, right user.

Example 3: Set the region

Type this:

aws configure set region ap-south-1
aws configure get region

You will see:

ap-south-1

What it means: All commands now use Mumbai.

Step 2: Create a repository

Why: An image needs a repository before you can push.

What: aws ecr create-repository makes one. Turn on scan on push and immutable tags from day one.

Example 4: Create

Type this:

aws ecr create-repository --repository-name shop-api --image-scanning-configuration scanOnPush=true --image-tag-mutability IMMUTABLE --query 'repository.repositoryUri' --output text

You will see:

111122223333.dkr.ecr.ap-south-1.amazonaws.com/shop-api

What it means: This URI is the full image name to use.

Example 5: List repositories

Type this:

aws ecr describe-repositories --query 'repositories[].repositoryName' --output text

You will see:

shop-api

What it means: One repository.

Example 6: Create twice

Type this:

aws ecr create-repository --repository-name shop-api

You will see:

An error occurred (RepositoryAlreadyExistsException) ...

What it means: Safe to see; nothing breaks. In scripts, check with describe-repositories first.

Step 3: Log Docker in to ECR

Why: Docker cannot push to ECR without a token.

What: ECR tokens last 12 hours. The username is always AWS. Pipe the token into docker login.

Example 7: Log in

Type this:

aws ecr get-login-password | docker login --username AWS --password-stdin 111122223333.dkr.ecr.ap-south-1.amazonaws.com

You will see:

Login Succeeded

What it means: Valid for 12 hours.

Example 8: Save the registry in a variable

Type this:

REG=111122223333.dkr.ecr.ap-south-1.amazonaws.com
echo $REG

You will see:

111122223333.dkr.ecr.ap-south-1.amazonaws.com

What it means: Shorter commands from now on.

Example 9: Wrong region

Type this:

aws ecr get-login-password --region us-east-1 | docker login -u AWS --password-stdin $REG

You will see:

Error response from daemon: ... 400 Bad Request

What it means: The token's region must match the registry's region.

3. Push and pull

Step 4: Tag and push

Why: This is the daily job of every CI pipeline.

What: Tag the local image with the repository URI and a version, then push.

Example 10: Tag

Type this:

docker tag shop-api:1.0 $REG/shop-api:1.0

You will see:

(no output)

What it means: Same image, ECR name.

Example 11: Push

Type this:

docker push $REG/shop-api:1.0

You will see:

The push refers to repository [111122223333.dkr.ecr.ap-south-1.amazonaws.com/shop-api]
5f70bf18a086: Pushed
1.0: digest: sha256:4b8e... size: 1987

What it means: Uploaded to your account.

Example 12: List images in ECR

Type this:

aws ecr list-images --repository-name shop-api --query 'imageIds[].imageTag' --output text

You will see:

1.0

What it means: The tag is there.

Step 5: Immutable tags

Why: At a payments company, someone re-pushed 1.0 with untested code, and prod pulled it.

What: With IMMUTABLE set, ECR refuses a push that would move an existing tag to new content.

Example 13: Change code, same tag

Type this:

printf 'hotfix\n' >> index.html
docker build -q -t $REG/shop-api:1.0 .
docker push $REG/shop-api:1.0

You will see:

tag invalid: The image tag '1.0' already exists in the 'shop-api' repository and cannot be overwritten because the repository is immutable.

What it means: Blocked, as planned.

Example 14: Use a new tag

Type this:

docker tag $REG/shop-api:1.0 $REG/shop-api:1.0.1
docker push $REG/shop-api:1.0.1 | tail -1

You will see:

1.0.1: digest: sha256:a3c4... size: 1987

What it means: Every change gets a new version.

Example 15: Check the setting

Type this:

aws ecr describe-repositories --repository-names shop-api --query 'repositories[0].imageTagMutability' --output text

You will see:

IMMUTABLE

What it means: Confirmed.

Step 6: Pull from ECR

Why: Servers need to pull the image you pushed.

What: Any machine with ECR read rights logs in the same way and pulls.

Example 16: Pull

Type this:

docker pull $REG/shop-api:1.0.1 | tail -1

You will see:

111122223333.dkr.ecr.ap-south-1.amazonaws.com/shop-api:1.0.1

What it means: Downloaded.

Example 17: Run

Type this:

docker run -d -p 80:80 --name shop $REG/shop-api:1.0.1
curl -s localhost | tail -1

You will see:

hotfix

What it means: Running the ECR image.

Example 18: Without login

Type this:

docker logout $REG
docker pull $REG/shop-api:1.0.1

You will see:

Error response from daemon: pull access denied ... no basic auth credentials

What it means: ECR has no anonymous pulls for private repositories.

EC2 instancehas an IAM roleRole policyECR read-onlyaws ecr get-login-passworduses the role, no keysdocker pullworks
Picture 2: EC2 pulls with a role

Step 7: EC2 pulls with an IAM role

Why: Putting access keys on servers is how keys leak.

What: Attach an IAM role to the EC2 with the AWS managed policy AmazonEC2ContainerRegistryReadOnly. The CLI on the server picks up temporary credentials by itself.

Example 19: Attach the policy to the role

Type this:

aws iam attach-role-policy --role-name shop-ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly

You will see:

(no output)

What it means: The role can now read from ECR.

Example 20: On the EC2, check identity

Type this:

aws sts get-caller-identity --query Arn --output text

You will see:

arn:aws:sts::111122223333:assumed-role/shop-ec2-role/i-0abc123

What it means: No keys on disk; the role is used.

Example 21: Log in and pull

Type this:

aws ecr get-login-password | docker login -u AWS --password-stdin $REG
docker pull $REG/shop-api:1.0.1 | tail -1

You will see:

Login Succeeded
111122223333.dkr.ecr.ap-south-1.amazonaws.com/shop-api:1.0.1

What it means: Works with the role alone.

Step 8: Auto login with the credential helper

Why: Tokens expire after 12 hours, and night jobs fail.

What: The Amazon ECR credential helper gets a fresh token every time Docker needs one.

Example 22: Install

Type this:

sudo apt-get install -y amazon-ecr-credential-helper
docker-credential-ecr-login version

You will see:

Setting up amazon-ecr-credential-helper ...
0.8.0

What it means: A small program Docker calls.

Example 23: Tell Docker to use it

Type this:

mkdir -p ~/.docker
printf '{\n  "credHelpers": {"111122223333.dkr.ecr.ap-south-1.amazonaws.com": "ecr-login"}\n}\n' > ~/.docker/config.json

You will see:

(no output)

What it means: Only this registry uses the helper.

Example 24: Pull with no docker login

Type this:

docker pull $REG/shop-api:1.0.1 | tail -1

You will see:

111122223333.dkr.ecr.ap-south-1.amazonaws.com/shop-api:1.0.1

What it means: No login step, and no expiry problems.

4. Keep it safe and tidy

Step 9: Scan on push

Why: Security teams at HDFC want to know about known bugs before deploy.

What: With scanOnPush=true, ECR scans each new image for known security problems (CVEs) in its packages.

Example 25: Wait for the scan

Type this:

aws ecr wait image-scan-complete --repository-name shop-api --image-id imageTag=1.0.1

You will see:

(no output)

What it means: Returns when the scan is done.

Example 26: Read the summary

Type this:

aws ecr describe-image-scan-findings --repository-name shop-api --image-id imageTag=1.0.1 --query 'imageScanFindings.findingSeverityCounts'

You will see:

{
  "HIGH": 2,
  "MEDIUM": 7,
  "LOW": 12
}

What it means: Two high problems. Your counts will differ.

Example 27: List the high ones

Type this:

aws ecr describe-image-scan-findings --repository-name shop-api --image-id imageTag=1.0.1 --query 'imageScanFindings.findings[?severity==`HIGH`].name' --output text

You will see:

CVE-YYYY-NNNNN CVE-YYYY-MMMMM

What it means: Placeholders here; your output shows real CVE numbers. Update the base image and rebuild.

Step 10: Lifecycle policy

Why: CI pushes every commit; after a year, ECR holds thousands of images and costs money.

What: A lifecycle policy deletes old images by rules, for example keep only the last 20.

Example 28: Write the policy

Type this:

printf '{"rules":[{"rulePriority":1,"description":"keep last 20","selection":{"tagStatus":"any","countType":"imageCountMoreThan","countNumber":20},"action":{"type":"expire"}}]}\n' > lc.json

You will see:

(no output)

What it means: One rule: more than 20 images, expire the oldest.

Example 29: Apply it

Type this:

aws ecr put-lifecycle-policy --repository-name shop-api --lifecycle-policy-text file://lc.json --query repositoryName --output text

You will see:

shop-api

What it means: ECR runs it by itself.

Example 30: Preview first

Type this:

aws ecr start-lifecycle-policy-preview --repository-name shop-api --query status --output text

You will see:

IN_PROGRESS

What it means: The preview lists what would be deleted, without deleting.

Step 11: Clean up

Why: Practice repositories cost a little every month.

What: Delete images, then the repository.

Example 31: Delete one image

Type this:

aws ecr batch-delete-image --repository-name shop-api --image-ids imageTag=1.0 --query 'imageIds[].imageTag' --output text

You will see:

1.0

What it means: Only that tag.

Example 32: Delete the repository

Type this:

aws ecr delete-repository --repository-name shop-api --force --query repository.repositoryName --output text

You will see:

shop-api

What it means: --force removes it with all images. Only for practice repos.

Example 33: Local cleanup

Type this:

docker rm -f shop
docker rmi $REG/shop-api:1.0.1 $REG/shop-api:1.0

You will see:

shop
Untagged: ...

What it means: Done.

Ravindra Bagale's Tip

Never keep access keys on an EC2. Attach AmazonEC2ContainerRegistryReadOnly to its IAM role. When you create a repository, turn on immutable tags and scan on push right away.

Check yourself

Q1. What username does ECR login use?

AWS.

Q2. How long does an ECR login token last?

12 hours.

Q3. What does IMMUTABLE stop?

Pushing new content to an existing tag.

Q4. How should EC2 get pull rights?

An IAM role with ECR read-only policy.

Q5. What does a lifecycle policy do?

Deletes old images by rules, such as keeping the last 20.

Friends, ECR is the company locker: protected by IAM, checked by scans, kept stable by immutable tags. Did you understand? Let us try it once more. If not, look at Pictures 1 and 2 again.

Lab: try at home

  1. Create shop-api in ECR with scan on push and immutable tags.
  2. Log in, tag and push version 1.0.
  3. Try to overwrite 1.0 and read the error.
  4. Give an EC2 a read-only role and pull without keys.
  5. Add a keep-last-20 lifecycle policy and preview it.

Recap

  • ECR is a private registry in your AWS account.
  • Login uses get-login-password, valid for 12 hours.
  • Immutable tags stop overwrites.
  • Servers pull with IAM roles, not keys.
  • Scan on push and lifecycle policies keep it safe and cheap.

Ravi Sir's Cards for this lesson

मराठी cards