Back to Blog

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

AI Transformation Lead
  • 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

Stuck between an AI pilot and a system your team can run?

I join your engineering team and build the agent layer alongside you, covering architecture, MCP integration, evals, and production deployment. When the engagement ends, your team owns the system 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.

Questions about this piece

Follow-ups readers ask most often about the argument above.

  • Run: aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com. The token is valid for 12 hours. In CI/CD, use the aws-actions/amazon-ecr-login GitHub Action with OIDC instead of static credentials.

  • After authenticating, run: docker pull <account>.dkr.ecr.<region>.amazonaws.com/<repo>:<tag>. Use aws ecr list-images --repository-name <repo> to discover available tags before pulling.

  • Yes. Use docker image save <image-url> > img.tar then tar -xf img.tar to extract all layers. Read manifest.json to understand layer order, then extract individual layer tarballs to inspect the filesystem without a container runtime.

  • Inspector v2 continuously monitors ECR images for CVEs, scanning on every push and re-scanning when new vulnerabilities are published. Enable it with: aws inspector2 enable --resource-types ECR, then set CONTINUOUS_SCAN on your repositories.

  • Your IAM entity needs ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer, and ecr:BatchGetImage to pull images. For pushes, also add ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, and ecr:PutImage. In CI/CD, use OIDC federation with a scoped role instead of static access keys.

  • Use aws ecr put-lifecycle-policy to define rules such as: keep the last 10 tagged images matching a prefix, and expire untagged images after 7 days. This prevents unbounded image accumulation that silently inflates AWS bills.

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.