Back to Blog

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

  • AWS
  • DevOps
  • Docker
  • ECR
  • Security
  • CI/CD
  • GitHub Actions
  • Container
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
AI Engineering for B2B

Building an AI feature your team can't finish?

Most AI projects stall because nobody on the team knows how to design agents, manage token budgets, or wire production evals. I build that layer for B2B companies so the feature actually ships and keeps shipping.

12+ years shipping production systems

Senior engineer turned AI specialist. React, Next.js, AWS, agent orchestration.

Dubai-based, working with B2B teams worldwide

Direct collaboration across UAE, Europe, and US time zones.

AI agent teams that ship, not demos that stall

Discovery, role design, MCP integration, evals, and production deployment.

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.