Links#
- Amazon ECR User Guide
- Creating an Amazon ECR private repository
- Pushing a Docker image to an Amazon ECR private repository
- Moving an image through its lifecycle in Amazon ECR
- aws ecr get-login-password
1. Important Points#
Amazon ECR 是 AWS 的 container image registry。常见用途是给 ECS / EKS / Lambda container image / App Runner 存放私有镜像。
ECR 用来做:
store private container images
push images from CI/CD
pull images from ECS / EKS / EC2 / Lambda
scan images
apply lifecycle policy
replicate images across regions/accounts
ECR 不负责:
build image
run container
deploy application
replace Dockerfile security practices核心原则:
repository:
one app/service usually has one repository
use lowercase name, optionally with namespace: platform/order-api
tag:
avoid relying only on latest
use immutable deploy tags, for example git sha or build timestamp
keep human-readable tags only as convenience
security:
push principal needs limited ECR write permissions
runtime role only needs pull permissions
do not expose images across accounts without repository policy2. Core Concepts#
| Concept | Meaning | Example |
|---|---|---|
| Registry | account + region registry endpoint | 111122223333.dkr.ecr.ap-east-1.amazonaws.com |
| Repository | image namespace inside registry | base/node |
| Image tag | mutable or immutable label | 22-alpine |
| Image digest | immutable content address | sha256:... |
| Authorization token | Docker login credential from AWS CLI | valid for 12 hours |
| Lifecycle policy | cleanup old images | keep last N tags |
| Repository policy | cross-account / principal access | allow another account pull |
Registry format:
<aws_account_id>.dkr.ecr.<region>.amazonaws.comImage format:
<aws_account_id>.dkr.ecr.<region>.amazonaws.com/<repository>:<tag>3. IAM#
Push principal minimum actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
"ecr:DescribeRepositories",
"ecr:DescribeImages"
],
"Resource": "arn:aws:ecr:ap-east-1:111122223333:repository/base/node"
}
]
}Pull principal minimum actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability"
],
"Resource": "arn:aws:ecr:ap-east-1:111122223333:repository/base/node"
}
]
}Notes:
ecr:GetAuthorizationToken:
resource must be "*"
push:
used by CI/CD, Jenkins, GitHub Actions, GitLab CI, developer machine
pull:
used by ECS task execution role, EKS node/pod role, EC2 instance role4. Repository Configuration#
Create repository:
aws ecr create-repository --repository-name base/node --image-tag-mutability IMMUTABLE \
--image-scanning-configuration scanOnPush=true --region ap-east-1Check:
aws ecr describe-repositories --repository-names base/node --region ap-east-1Recommended defaults:
image tag immutability:
enable for deploy repositories
prevents accidental overwrite of existing tags
scan on push:
useful baseline
for stronger security, configure ECR registry scanning / Inspector where available
KMS:
default encryption is usually enough
use customer managed KMS key only when compliance requires it5. Push Docker Hub Image To ECR#
目标:把 Docker Hub 的 node:22-alpine 下载到本地,重新打 ECR tag,登录 ECR,再 push 到 ECR。
Example values:
export AWS_REGION=ap-east-1
export AWS_ACCOUNT_ID=111122223333
export ECR_REPOSITORY=base/node
export SOURCE_IMAGE=node:22-alpine
export ECR_IMAGE="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:22-alpine"Create repository if needed:
aws ecr create-repository --repository-name "${ECR_REPOSITORY}" --image-tag-mutability IMMUTABLE \
--image-scanning-configuration scanOnPush=true --region "${AWS_REGION}"Pull from Docker Hub:
docker pull "${SOURCE_IMAGE}"
docker images "${SOURCE_IMAGE}"Tag for ECR:
docker tag "${SOURCE_IMAGE}" "${ECR_IMAGE}"
docker images "${ECR_IMAGE}"Login to ECR:
aws ecr get-login-password --region "${AWS_REGION}" \
| docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"Push to ECR:
docker push "${ECR_IMAGE}"Verify:
aws ecr describe-images --repository-name "${ECR_REPOSITORY}" \
--image-ids imageTag=22-alpine --region "${AWS_REGION}"Pull back from ECR:
docker pull "${ECR_IMAGE}"Expected:
docker push:
layers are pushed or reused
output ends with digest: sha256:...
describe-images:
imageTag contains 22-alpine
imageDigest is present
imagePushedAt is recentCommon mistakes:
repository does not exist:
create repository first, unless using repository creation template
no basic auth credentials:
run aws ecr get-login-password | docker login again
ImageTagAlreadyExistsException:
repository is immutable and tag already exists
use a new tag or delete old image intentionally
wrong region/account:
registry endpoint must match target AWS account and region
Docker Hub rate limit:
use ECR pull through cache or mirror base images during CI setup6. Lifecycle Policy#
Example: keep recent images and avoid unbounded storage growth.
Important limitation:
ECR lifecycle policy:
tagPrefixList and tagPatternList are not regular expressions
tagPatternList uses wildcard style matching, for example prod* or *prod*
native ECR lifecycle policy cannot directly express regex like ^(?!v).*
If your own UI/tool has an "Image tag filters" regex field:
use ^(?!v).* to match tags that do not start with v
For native ECR lifecycle policy:
prefer tag naming conventions such as build-*, sha-*, pr-*
then use tagPatternList / tagPrefixList on those prefixesRegex meaning for external tools:
^(?!v).*
^ start of tag
(?!v) next character is not v
.* rest of tag
matches:
22-alpine
build-20260612
sha-a1b2c3d
does not match:
v1.2.3
v20260612{
"rules": [
{
"rulePriority": 1,
"description": "Keep last 30 non-release node base images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["22-"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Expire untagged images after 7 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": {
"type": "expire"
}
}
]
}如果 tag 约定是:
release tags:
v1.2.3
v1.2.4
non-release build tags:
build-20260612-120000
sha-a1b2c3d可以用 ECR 原生 lifecycle policy 只评估 build tag:
{
"rules": [
{
"rulePriority": 1,
"description": "Expire old build tags, do not touch v release tags",
"selection": {
"tagStatus": "tagged",
"tagPatternList": ["build-*"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}如果当前已有大量非 v 开头 tag,但没有统一 prefix,ECR 原生 lifecycle policy 不能用一个 negative regex 覆盖它们。更好的做法是先统一新 tag 规则,或用外部清理脚本通过 describe-images 过滤 tag 后再删除。
Apply:
aws ecr put-lifecycle-policy \
--repository-name base/node \
--lifecycle-policy-text file://lifecycle-policy.json \
--region ap-east-17. Troubleshooting#
| Symptom | Check |
|---|---|
no basic auth credentials |
Docker is not logged in to target ECR registry |
repository does not exist |
repository name and region |
denied: User is not authorized |
IAM permissions for push/pull principal |
ImageTagAlreadyExistsException |
immutable tag already exists |
| push goes to wrong account | AWS_ACCOUNT_ID, AWS profile, registry URL |
| ECS cannot pull image | task execution role, private subnet egress/VPC endpoints |
Useful commands:
aws sts get-caller-identity
aws ecr describe-repositories --region ap-east-1
aws ecr describe-images --repository-name base/node --region ap-east-1
docker images
docker logout 111122223333.dkr.ecr.ap-east-1.amazonaws.com8. Checklist#
1. repository exists
2. region and account are correct
3. Docker is logged in to ECR
4. image is tagged with full ECR registry/repository/tag
5. push principal has least-privilege ECR write permissions
6. runtime principal has ECR pull permissions
7. lifecycle policy exists
8. tag immutability decision is explicit
9. ECS/EKS/EC2 pull path has network access to ECR