Docker Images on AWS: ECR Setup and Push
This chapter covers the end-to-end workflow of configuring an Amazon Web Services (AWS) Elastic Container Registry (ECR)—a secure, private container registry—building a custom Docker image on an EC2 instance, authenticating via the AWS CLI, tagging and pushing the image to ECR, and verifying role-based access control (RBAC) behavior between authenticated and unauthenticated hosts.
1. Why Do We Need a Private Registry? (The Problem Statement)
While public repositories like Docker Hub are ideal for open-source distributions, enterprise applications require strict data privacy, access control, and isolation.
- Public vs. Private Exposure: Public repositories expose images to the world, whereas private registries restrict consumption strictly to authorized internal teams, CI/CD pipelines, and microservices.
- Compliance & Security: Organizations must maintain ownership, encryption keys, and granular audit logs for all software artifacts. AWS ECR integrates seamlessly with AWS IAM (Identity and Access Management) and KMS (Key Management Service) to achieve this.
2. Core Mental Model: ECR as a GitHub for Docker Images
Real-Life Analogy: Think of an ECR repository like a private GitHub repository. Just as you create a Git repo to store, version-control, and collaborate on source code under specific team namespaces, an ECR repository namespaces and stores built Docker images so that only authorized servers can pull them.
3. Step 1: Provisioning the Build Server (Amazon EC2)
Before interacting with ECR, we need a remote Linux environment to act as our build host.
- Launch EC2 Instance:
- Choose an AMI (e.g., Amazon Linux or Ubuntu).
- Select the instance type and key pair (
.pemfile).
- Connect via SSH:
BASH
ssh -i "your-key.pem" ec2-user@<your-ec2-public-ip> - Elevate Privileges: Switch to a superuser to prevent permission denial issues during package installations and Docker daemon interactions:
BASH
sudo -i
4. Step 2: Installing Docker and Verifying Service Health
With root access secured, install Docker on the EC2 instance and ensure the daemon is running.
# Install Docker package
yum install docker
# Verify installed Docker version
docker --version
# Output: Docker version 25.0.14
# Check Docker service status
systemctl status docker
# (If inactive, restart the service)
systemctl restart Docker
# Verify service is active and running
systemctl status docker
5. Step 3: Configuring AWS ECR Repository via Console
Next, set up the private repository inside the AWS Management Console:
- Search for Elastic Container Registry (ECR) in the AWS Console dashboard.
- Click Create repository.
- Configure settings:
- Repository Type: Private
- Namespace / Repository Name:
development/core(wheredevelopmentacts as the isolation namespace, andcorerepresents the specific microservice). - Tag immutability: Set to Immutable to prevent developers from accidentally overwriting existing image tags in production.
- Encryption configuration: Select AWS KMS (Key Managed Service) managed by Amazon for robust encryption-at-rest.
- Click Create repository.
6. Step 4: Installing and Configuring AWS CLI on the Build Instance
To allow our EC2 instance to communicate with ECR, we must install the AWS CLI and configure security credentials.
Installing AWS CLI (Linux)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Verify installation
aws --version
Configuring AWS Credentials
To prevent An error occurred (NoCredentialsError) when calling the ListUsers operation, configure your IAM programmatic credentials:
aws configure
Provide the following prompts when requested:
- AWS Access Key ID: Your IAM user access key.
- AWS Secret Access Key: Your IAM user secret key.
- Default region name: e.g.,
us-east-1 - Default output format: e.g.,
json
Verify the configuration by listing IAM users:
aws iam list-users
7. Step 5: Building, Tagging, and Pushing Images to ECR
Navigate to the ECR console and click View push commands to review the exact sequence required for your registry URI (<aws_account_id>.dkr.ecr.<region>.amazonaws.com/development/core).
1. Authenticate Docker Client to ECR
Retrieve an authentication token and pass it to your local Docker daemon:
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com
- Success Message:
Login Succeeded
2. Create a Dockerfile
Create a basic Dockerfile in your working directory:
FROM alpine:latest
CMD ["echo", "Hello from ECR Private Repository!"]
3. Build the Local Docker Image
docker build -t development/core .
4. Tag the Image for ECR
Tag your local image (development/core:latest) to match the private registry URI:
docker tag development/core:latest <aws_account_id>.dkr.ecr.<region>.amazonaws.com/development/core:latest
5. Push the Image to ECR
docker push <aws_account_id>.dkr.ecr.<region>.amazonaws.com/development/core:latest
Once complete, return to the AWS ECR console, refresh the repository view, and verify that the latest image tag is successfully listed.
8. Step 6: Security Verification (Authenticated vs. Unauthenticated Pulls)
To validate that ECR private repositories enforce access controls, perform isolation testing across different hosts.
Test A: Pulling as an Authenticated User
On our configured EC2 instance (which has valid credentials and has logged into ECR):
# Clear local images to test clean pull
docker rmi -f $(docker images -q)
# Pull image from private ECR
docker pull <aws_account_id>.dkr.ecr.<region>.amazonaws.com/development/core:latest
- Result: Success. The authenticated client pulls the image without errors.
Test B: Pulling as an Unauthenticated User
Provision a brand-new EC2 instance (Ubuntu/Amazon Linux) without running aws configure or executing docker login:
# Attempt to pull the private image directly
docker pull <aws_account_id>.dkr.ecr.<region>.amazonaws.com/development/core:latest
- Result: Failure.
TEXT
Error response from daemon: Head "https://<aws_account_id>.dkr.ecr.<region>.amazonaws.com/v2/development/core/manifests/latest": no basic auth credentials - Conclusion: Private ECR repositories successfully block unauthorized external pulls, ensuring container artifacts remain secure within enterprise boundaries.
Summary and Key Takeaways
- Private vs. Public Registries: ECR provides private, highly secure container image storage compared to public registries like Docker Hub.
- Namespace Isolation: Repositories are organized using namespaces (e.g.,
development/core) to isolate environments and services logically. - Tag Immutability: Configuring tags as immutable prevents accidental overwriting of production image versions.
- KMS Encryption: AWS KMS integration guarantees robust encryption-at-rest for all stored container layers.
- AWS CLI Authentication: Docker clients must authenticate with ECR using a token generated dynamically via
aws ecr get-login-password. - Registry Workflow: The standard lifecycle involves
aws ecr get-login-password->docker build->docker tag->docker push. - Access Control Enforcement: Unauthenticated hosts trying to pull private images fail immediately with a
no basic auth credentialserror, proving the effectiveness of ECR's security boundary.