Authenticate Docker with a Private ECR Registry
Use aws ecr get-login-password piped to docker login to authenticate with a private Amazon ECR registry. Cross-region included.
aws ecr get-login-password returns a short-lived token, which you pipe directly into docker login to authenticate Docker against a private Amazon ECR registry. This is the canonical command for pushing and pulling Docker images from ECR. Run it once per session (the token lasts 12 hours) and Docker is good to go.
Tested on AWS CLI v2.17, Docker 25+.
When to Use This
- Pushing a freshly built Docker image to ECR
- Pulling a private image for local development
- Running
docker compose upwith images stored in ECR - Setting up CI/CD pipelines that interact with ECR
Don't use this when the credential helper is available (better DX, auto-refresh) or when you're inside an EC2/ECS/Lambda context with an instance role (Docker can use those directly via the helper).
Code
# The canonical one-liner
aws ecr get-login-password --region $REGION \
| docker login --username AWS --password-stdin $ACCOUNT.dkr.ecr.$REGION.amazonaws.com
# Concrete example
aws ecr get-login-password --region ap-south-1 \
| docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-south-1.amazonaws.comThe --password-stdin flag is essential. Without it, the password ends up in your shell history and process list. With it, Docker reads the password from stdin and never exposes it.
Usage
A complete build-and-push workflow:
#!/usr/bin/env bash
set -euo pipefail
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
REGION="ap-south-1"
REPO="my-app"
TAG="${1:-latest}"
REGISTRY="${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com"
# 1) Authenticate Docker with ECR
echo "→ Authenticating Docker with ECR..."
aws ecr get-login-password --region "$REGION" \
| docker login --username AWS --password-stdin "$REGISTRY"
# 2) Build the image
echo "→ Building image..."
docker build -t "${REPO}:${TAG}" .
# 3) Tag for ECR
docker tag "${REPO}:${TAG}" "${REGISTRY}/${REPO}:${TAG}"
# 4) Push
echo "→ Pushing to ${REGISTRY}/${REPO}:${TAG}..."
docker push "${REGISTRY}/${REPO}:${TAG}"
echo "✓ Done"The script auto-detects the AWS account ID via sts get-caller-identity, so you don't have to hardcode it. Drop it in scripts/deploy-image.sh and call with ./scripts/deploy-image.sh v1.2.3.
Caveats
- The token expires after 12 hours. If you're getting
unauthorizederrors after a long workday, re-run the login command. - Region matters in the registry URL. The registry domain is
<account>.dkr.ecr.<region>.amazonaws.com— wrong region means wrong registry, even if the repo name is identical. --username AWSis literal. That's the actual username, not a placeholder. Don't replace it with your IAM username.- Cross-account pushes need the target account's registry URL. And the target ECR repo policy must allow your principal. Common confusion when migrating images between accounts.
- The login is per-registry, not per-repo. Once authenticated against
123456789012.dkr.ecr.ap-south-1.amazonaws.com, every repo in that account/region is accessible. - Credentials are stored in
~/.docker/config.json. They're plain text by default. Set up the credential helper for production machines.
Related Snippets & Reading
- Debug Which AWS Identity You're Using — when login fails with access denied
- Assume an IAM Role from the CLI — for cross-account ECR pushes
- aws ecr get-login-password reference — official docs
Frequently Asked Questions
Why does docker login fail against ECR even when AWS CLI works?
ECR uses short-lived auth tokens that expire after 12 hours. docker login stores credentials separately from AWS CLI, so a fresh AWS session does not automatically re-authenticate Docker. You have to re-run get-login-password whenever the token expires.
Can you use the credential helper instead of get-login-password?
Yes — install amazon-ecr-credential-helper and configure Docker to use it. The helper auto-fetches a fresh token on every push/pull, so you never have to re-login. It's the right choice for long-running developer machines but adds setup steps.