Back to Blog

AWS ECR in 2026: Pull, Inspect, Scan & Automate Docker Images: Complete Guide

AWSDevOpsDockerECRSecurityCI/CDGitHub ActionsContainer
AWS ECR Docker image management with security scanning and GitHub Actions CI/CD

AWS Elastic Container Registry (ECR) is the default private Docker registry for AWS workloads. Teams interact with it dozens of times a day, but most only know the basics. This guide covers the full workflow: authenticate securely, pull and inspect images, extract filesystem layers without running a container, scan for CVEs with Amazon Inspector v2, manage costs through lifecycle policies, and automate everything with GitHub Actions OIDC.

Prerequisites

  • AWS CLI v2 installed and configured (aws configure)
  • Docker Engine ≥ 24 running locally
  • IAM user or role with ECR read permissions

Step 1: Authenticate to ECR

ECR uses short-lived tokens (12-hour TTL) tied to your AWS identity. Authenticate before any pull or push:

bash
# Replace <region> and <account-id> with your actual values aws ecr get-login-password --region us-east-1 \ | docker login --username AWS --password-stdin \ 123456789012.dkr.ecr.us-east-1.amazonaws.com

In automation, use the aws-actions/amazon-ecr-login GitHub Action (Step 7) instead of running this manually.

Step 2: Find Available Tags

bash
# List all image tags in a repository aws ecr list-images \ --repository-name my-repo \ --query 'imageIds[?imageTag!=null].imageTag' \ --output table

Step 3: Pull the Image

bash
docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest

Step 4: Inspect & Run Commands in the Image

Run a one-off command inside the image without a persistent container:

bash
# List root filesystem docker run --rm \ 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest \ ls -la / # Inspect baked-in environment variables docker run --rm \ 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest \ env # Override entrypoint for interactive exploration docker run --rm -it \ --entrypoint /bin/sh \ 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest

Step 5: Extract the Full Filesystem Without Running the Container

Useful for recovering lost Dockerfiles, auditing third-party images, or forensic investigation:

bash
# Save the image as a tar archive docker image save \ 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest \ > my-image.tar # Extract into a directory mkdir -p image-fs && tar -xf my-image.tar -C image-fs # Read the layer manifest (shows layer order) cat image-fs/manifest.json | python3 -m json.tool # Extract a specific layer to inspect its files mkdir layer0 && tar -xf image-fs/<layer-digest>/layer.tar -C layer0 # Search for env files or config across all layers find image-fs -name "*.env" -o -name "Dockerfile" 2>/dev/null

Each layer corresponds to a RUN, COPY, or ADD instruction in the original Dockerfile. Stacking them in manifest order reconstructs the final container filesystem.

Step 6: Security: Scan with Amazon Inspector v2

Amazon Inspector v2 continuously monitors ECR images for CVEs, scanning on push and re-scanning when new vulnerabilities are published.

Enable Enhanced Scanning

bash
# Enable Inspector v2 for ECR aws inspector2 enable --resource-types ECR # Configure continuous enhanced scanning for all repos aws ecr put-registry-scanning-configuration \ --scan-type ENHANCED \ --rules '[{ "repositoryFilters": [{"filter": "*", "filterType": "WILDCARD"}], "scanFrequency": "CONTINUOUS_SCAN" }]'

View Findings

bash
aws inspector2 list-findings \ --filter-criteria '{ "ecrImageRepositoryName": [{"comparison": "EQUALS", "value": "my-repo"}] }' \ --query 'findings[*].{ Severity: severity, CVE: packageVulnerabilityDetails.vulnerabilityId, Package: packageVulnerabilityDetails.vulnerablePackages[0].name }' \ --output table

Align remediation with severity: patch CRITICAL and HIGH immediately; schedule MEDIUM for the next sprint.

Step 7: Lifecycle Policies: Control Storage Costs

Without policies, ECR silently accumulates thousands of images. One lifecycle rule pays for itself immediately:

bash
aws ecr put-lifecycle-policy \ --repository-name my-repo \ --lifecycle-policy-text '{ "rules": [ { "rulePriority": 1, "description": "Keep last 10 versioned releases", "selection": { "tagStatus": "tagged", "tagPrefixList": ["v"], "countType": "imageCountMoreThan", "countNumber": 10 }, "action": { "type": "expire" } }, { "rulePriority": 2, "description": "Expire untagged images after 7 days", "selection": { "tagStatus": "untagged", "countType": "sinceImagePushed", "countUnit": "days", "countNumber": 7 }, "action": { "type": "expire" } } ] }'

Step 8: Full CI/CD Pipeline with GitHub Actions (OIDC)

Use OIDC federation, no static AWS credentials stored in GitHub Secrets:

yaml
# .github/workflows/ecr-deploy.yml name: Build & Push to ECR on: push: branches: [main] permissions: id-token: write # Required for OIDC contents: read jobs: build-push: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789012:role/github-ecr-push aws-region: us-east-1 - name: Login to ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - name: Build, tag & push env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} IMAGE_TAG: ${{ github.sha }} run: | docker build -t $REGISTRY/my-repo:$IMAGE_TAG . docker build -t $REGISTRY/my-repo:latest . docker push $REGISTRY/my-repo:$IMAGE_TAG docker push $REGISTRY/my-repo:latest

The OIDC role should have only the minimum ECR permissions: no full AmazonEC2ContainerRegistryFullAccess, scope it to ecr:GetAuthorizationToken + push operations on your specific repositories.

Quick Reference

| Task | Command | |------|---------|| | Authenticate | aws ecr get-login-password \| docker login ... | | List tags | aws ecr list-images --repository-name <repo> --query 'imageIds[?imageTag!=null].imageTag' | | Pull image | docker pull <ecr-url>/<repo>:<tag> | | Run command | docker run --rm --entrypoint /bin/sh <image> | | Extract FS | docker image save <image> > img.tar && tar -xf img.tar | | View CVEs | aws inspector2 list-findings ... | | Set lifecycle | aws ecr put-lifecycle-policy ... |

With Inspector v2 scanning every image on push and lifecycle policies preventing storage sprawl, ECR becomes a fully governed container supply chain, not just a registry.

X / Twitter
LinkedIn
Facebook
WhatsApp
Telegram

About Pooya Golchian

Common questions about Pooya's work, AI services, and how to start a project together.

Get practical AI and engineering playbooks

Weekly field notes on private AI, automation, and high-performance Next.js builds. Each edition is concise, implementation-ready, and tested in production work.

Open full subscription page

Get the latest insights on AI and full-stack development.