ECR
Amazon Elastic Container Registry for storing and managing Docker container images.
Configuration
| Property | Value |
|---|---|
| Protocol | AwsJson1_1 |
| Signing Name | ecr |
| Target Prefix | AmazonEC2ContainerRegistry_V20150921 |
| Persistence | No |
Quick Start
Create a repository, get a login token, and list images:
# Create a repository
curl -s http://localhost:4566 \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.CreateRepository" \
-H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/ecr/aws4_request, SignedHeaders=host, Signature=fake" \
-d '{"repositoryName":"my-app","imageScanningConfiguration":{"scanOnPush":false},"imageTagMutability":"MUTABLE"}'
# Get authorization token for docker login
curl -s http://localhost:4566 \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.GetAuthorizationToken" \
-H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/ecr/aws4_request, SignedHeaders=host, Signature=fake" \
-d '{}'Operations
Repositories
CreateRepository— create a new image repository- Input:
repositoryName(required),imageTagMutability(MUTABLEorIMMUTABLE),imageScanningConfiguration({scanOnPush: bool}),encryptionConfiguration,tags - Returns:
repositorywithrepositoryArn,repositoryUri(e.g.,000000000000.dkr.ecr.us-east-1.amazonaws.com/my-app),createdAt
- Input:
DeleteRepository— delete a repository and all its images- Input:
repositoryName, optionalforce(boolean, required if repository contains images)
- Input:
DescribeRepositories— list repositories with optional filter- Input: optional
repositoryNames(list),maxResults,nextToken - Returns: paginated
repositorieslist
- Input: optional
Authorization
GetAuthorizationToken— get a temporary Docker login token for the registry- Input: optional
registryIds(list) - Returns:
authorizationDatalist, each withauthorizationToken(base64-encodedAWS:password),expiresAt,proxyEndpoint - Decode the token and use as Docker credentials:
echo $TOKEN | base64 -dgivesAWS:password
- Input: optional
Images
PutImage— push an image manifest to a repository- Input:
repositoryName,imageManifest(JSON string), optionalimageTag,imageDigest - Returns:
imagewithimageIdcontainingimageDigestandimageTag
- Input:
BatchGetImage— retrieve image manifests by tag or digest- Input:
repositoryName,imageIds(list of{imageTag}or{imageDigest}) - Returns:
imageslist with manifests,failuresfor not-found images
- Input:
BatchDeleteImage— delete one or more images by tag or digest- Input:
repositoryName,imageIds(list of{imageTag}or{imageDigest}) - Returns:
imageIds(deleted) andfailures
- Input:
ListImages— list image IDs (tags and digests) in a repository- Input:
repositoryName, optionalfilter({tagStatus: "TAGGED"/"UNTAGGED"}),maxResults,nextToken - Returns: paginated
imageIdslist
- Input:
DescribeImages— get detailed image metadata including size and push date- Input:
repositoryName, optionalimageIds,maxResults,nextToken - Returns:
imageDetailslist withimageSizeInBytes,imagePushedAt,imageTags,imageDigest
- Input:
Tags
TagResource— add tags to a repository (by ARN)UntagResource— remove tags from a repositoryListTagsForResource— list tags on a repository
Lifecycle Policies
PutLifecyclePolicy— set the lifecycle policy for a repository- Input:
repositoryName,lifecyclePolicyText(JSON policy string)
- Input:
GetLifecyclePolicy— retrieve the lifecycle policy for a repository- Input:
repositoryName - Returns:
lifecyclePolicyText,lastEvaluatedAt
- Input:
DeleteLifecyclePolicy— remove the lifecycle policy from a repository- Input:
repositoryName
- Input:
Repository Policies
SetRepositoryPolicy— set an IAM-style access policy on a repository- Input:
repositoryName,policyText(JSON policy string), optionalforce
- Input:
GetRepositoryPolicy— retrieve the access policy for a repository- Input:
repositoryName - Returns:
policyText
- Input:
DeleteRepositoryPolicy— remove the access policy from a repository- Input:
repositoryName
- Input:
Image Scanning
StartImageScan— initiate a vulnerability scan for an image (immediately returns COMPLETE)- Input:
repositoryName,imageId({imageTag}or{imageDigest})
- Input:
DescribeImageScanFindings— retrieve scan results for an image (stub: returns no findings)- Input:
repositoryName,imageId - Returns:
imageScanFindingswith emptyfindingslist
- Input:
Layer Operations
GetDownloadUrlForLayer— return a download URL for a layer (stub URL)- Input:
repositoryName,layerDigest - Returns:
downloadUrl,layerDigest
- Input:
BatchCheckLayerAvailability— check if layers exist (returns all as AVAILABLE)- Input:
repositoryName,layerDigests - Returns:
layerslist withlayerAvailability: "AVAILABLE"
- Input:
InitiateLayerUpload— start a layer upload session- Input:
repositoryName - Returns:
uploadId,lastByteReceived: 0
- Input:
UploadLayerPart— upload a part of a layer- Input:
repositoryName,uploadId,partFirstByte,partLastByte,layerPartBlob - Returns:
uploadId,lastByteReceived
- Input:
CompleteLayerUpload— finalize a layer upload and compute its digest- Input:
repositoryName,uploadId,layerDigests(client-expected digests) - Returns:
uploadId,layerDigest(SHA-256 of uploaded data)
- Input:
Curl Examples
# 1. Create a repository with scanning enabled
curl -s http://localhost:4566 \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.CreateRepository" \
-H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/ecr/aws4_request, SignedHeaders=host, Signature=fake" \
-d '{"repositoryName":"backend","tags":[{"Key":"team","Value":"platform"}]}'
# 2. List all repositories
curl -s http://localhost:4566 \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.DescribeRepositories" \
-H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/ecr/aws4_request, SignedHeaders=host, Signature=fake" \
-d '{}'
# 3. Delete image by tag
curl -s http://localhost:4566 \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.BatchDeleteImage" \
-H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/ecr/aws4_request, SignedHeaders=host, Signature=fake" \
-d '{"repositoryName":"my-app","imageIds":[{"imageTag":"latest"},{"imageTag":"v1.0.0"}]}'SDK Example
import {
ECRClient,
CreateRepositoryCommand,
GetAuthorizationTokenCommand,
DescribeRepositoriesCommand,
ListImagesCommand,
} from '@aws-sdk/client-ecr';
const ecr = new ECRClient({
region: 'us-east-1',
endpoint: 'http://localhost:4566',
credentials: { accessKeyId: 'test', secretAccessKey: 'test' },
});
// Create repository
const { repository } = await ecr.send(new CreateRepositoryCommand({
repositoryName: 'my-app',
imageTagMutability: 'MUTABLE',
}));
console.log('Registry URI:', repository?.repositoryUri);
// e.g., 000000000000.dkr.ecr.us-east-1.localhost.localstack.cloud:4566/my-app
// Get login token
const { authorizationData } = await ecr.send(new GetAuthorizationTokenCommand({}));
const tokenData = authorizationData?.[0];
const [username, password] = Buffer.from(tokenData!.authorizationToken!, 'base64')
.toString()
.split(':');
console.log('Docker login user:', username); // AWS
console.log('Registry endpoint:', tokenData?.proxyEndpoint);
// List repositories
const { repositories } = await ecr.send(new DescribeRepositoriesCommand({}));
console.log('Repositories:', repositories?.map(r => r.repositoryName));Behavior Notes
- The authorization token returned by
GetAuthorizationTokenis a valid base64-encoded string inAWS:tokenformat but does not perform real authentication against a Docker registry. - Image manifests are stored as JSON strings; no image layer validation, decompression, or content-addressable storage occurs.
- ECR does not integrate with a real Docker registry —
docker push/pullcommands require a real registry endpoint. repositoryUrifollows the real AWS format:{accountId}.dkr.ecr.{region}.amazonaws.com/{name}.- State is in-memory only and lost on restart.