93

Im new to AWS. I want to set up a private docker repository on an AWS ECS container instance. I created a repository named name. The example push commands shown by AWS are working.

aws ecr get-login --region us-west-2 
docker build -t name .
docker tag name:latest ############.dkr.ecr.us-west-2.amazonaws.com/name:latest 
docker push ############.dkr.ecr.us-west-2.amazonaws.com/name:latest

But with this commands I build and pushed an image named name and I want to build an image named foo. So I altered the commands to:

docker build -t foo .
docker tag foo ###########.dkr.ecr.us-west-2.amazonaws.com/name/foo
docker push ###########.dkr.ecr.us-west-2.amazonaws.com/name/foo

This should work, but it doesn't. After a period of retrys I get the error:

The push refers to a repository [###########.dkr.ecr.us-west-2.amazonaws.com/name/foo]
8cc63cf4528f: Retrying in 1 second
...
name unknown: The repository with name 'name/foo' does not exist in the registry with id '############'

Does AWS really require a dedicated repository for every image i want to push?

Ohmen
  • 6,194
  • 3
  • 25
  • 35

7 Answers7

89

The EC2 Container Registry requires an image Repository to be setup for each image "name" or "namespace/name" you want to publish to the registry.

You can publish any :tags you want in each Repository though (The default limit is 100 tags).

I haven't seen anywhere in the AWS documentation that specifically states the repository -> image name mapping but it's implied by Creating a Repository - Section 6d in the ECR User Guide

The Docker Image spec includes it's definition of a Repository

Repository

A collection of tags grouped under a common prefix (the name component before :). For example, in an image tagged with the name my-app:3.1.4, my-app is the Repository component of the name. A repository name is made up of slash-separated name components, optionally prefixed by a DNS hostname. The hostname must comply with standard DNS rules, but may not contain _ characters. If a hostname is present, it may optionally be followed by a port number in the format :8080. Name components may contain lowercase characters, digits, and separators. A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.

Matt
  • 68,711
  • 7
  • 155
  • 158
  • 4
    ah.. I don't think AWS explicitly state that their ECR Repository concept relates to a single Docker image `name` or `namespace/name`. The first time it took me a couple of attempts to figure it out. Section 6d on https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html implies the one name/multiple tag repository setup with an image build tag of `repository:latest` – Matt Nov 30 '16 at 02:47
  • 6
    @Matt I wish they(aws) would nail this down and make that a hard fact. I don't like loose interpretations, as their doc is written. – Kuberchaun Jan 27 '17 at 00:28
  • @GoatWalker AWS uses the same concept as on the old, official [Docker hub](https://hub.docker.com): * A *repository* contains *one* [image name](https://docs.docker.com/engine/reference/commandline/tag/#/extended-description). * An *image* is a specific Docker build, which should be *tag*ged accordingly. Docker changed the naming of “repository” to “*containers*” the official [Docker store](https://store.docker.com/), which supersedes the Docker hub. Not to confuse with the running containers ;-) – Dominik Mar 02 '17 at 12:44
  • 1
    supersedes is a strong term that Docker marketing would like you to buy into. hub isn't going anywhere, and can even be the source for a "free" Store image. – Matt Mar 15 '17 at 23:45
  • Looks like 100 tags per image btw (http://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html) – demaniak May 26 '17 at 11:48
  • @Matt I have a similar error issue and I have checked all you mentioned but I still get the same error. I am doing this from my GitHub actions build file tho', could you help with some insights? – Sam Bayo May 19 '21 at 15:09
60

You need to create a repository for each image name, but the image name can be of the form "mycompanyname/helloworld". So you create mycompanyname/app1, mycompanyname/app2, etc

aws ecr create-repository --repository-name mycompanyname/helloworld
aws ecr create-repository --repository-name mycompanyname/app1
aws ecr create-repository --repository-name mycompanyname/app2
docker tag helloworld:latest xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/helloworld:latest
docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/helloworld:latest
docker tag app1:latest xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/app1:latest
docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/mycompanyname/app1:latest
RubenLaguna
  • 21,435
  • 13
  • 113
  • 151
8

I tried the following steps and confirmed working for me:

  1. aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com

  2. aws ecr create-repository --repository-name test

  3. docker build -t test .

  4. docker tag test:latest xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/test:latest

  5. docker push xxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/test:latest

Steven Shi
  • 81
  • 1
  • 2
2

Addition to the above answer, I came across here today, as the login command change with aws-cli v2, posting as an answer might help others. as aws-cli v1 login command no longer work.

V1
$(aws ecr get-login --no-include-email)

To push image to ECR using aws-cli v2 you need

aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-west-2.amazonaws.com

Then you are okay to build and push

docker build -t myrepo .
docker tag myrepo:latest 123456789.dkr.ecr.us-west-2.amazonaws.com/myrepo
docker push 123456789.dkr.ecr.us-west-2.amazonaws.com/myrepot

Typically One image per registry is a clean approach, that why AWS increase image per repository and repository per region from 1000 to 10,000.

Adiii
  • 54,482
  • 7
  • 145
  • 148
0

For this i automated the script that can read your public images from csv file and pull them. After that it will try to create repository in ECR and push to registry.

  1. Prepare CSV file ecr-images.csv
docker.io/amazon/aws-for-fluent-bit,2.13.0
docker.io/couchdb,3.1
docker.io/bitnami/elasticsearch,7.13.1-debian-10-r0
k8s.gcr.io/kube-state-metrics/kube-state-metrics,v2.0.0
k8s.gcr.io/metrics-server-amd64,v0.3.6
--------------------KEEP THIS LINE AT END-------------------------
  1. Automated script ecr.sh that will copy images to ecr
#!/bin/bash

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

assert_value() {
  if [ -z "$1" ]; then
    echo "No args: $2"
    exit 1
  fi
}

repository_uri=$1
assert_value "$repository_uri" "repository_uri"

create_repo() {
    ## try to create & failure will ignored by <|| true>
    aws ecr create-repository --repository-name "$1" --output text || true
}

## Copy Docker Images to ECR
COUNTER=0
while IFS=, read -r dockerImage tag; do
  outputImage=$(echo "$dockerImage" | sed -E 's/(\w+?\.)+\w+?\///')
  outputImageUri="$repository_uri/$outputImage"
  # shellcheck disable=SC2219
  let COUNTER=COUNTER+1
  echo "--------------------------------------------------------------------------"
  echo "$COUNTER => $dockerImage:$tag pushing to $outputImageUri:$tag"
  echo "--------------------------------------------------------------------------"
  docker pull "$dockerImage:$tag"
  docker tag "$dockerImage:$tag" "$outputImageUri:$tag"
  create_repo "$outputImage"
  docker push "$outputImageUri:$tag"
done <"$SCRIPT_DIR/ecr-images.csv"
  1. Run
repository_uri=<ecr_account_id>.dkr.ecr.<ecr_region>.amazonaws.com

aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin $repository_uri

./ecr.sh $repository_uri
Bhuwan Prasad Upadhyay
  • 2,916
  • 1
  • 29
  • 33
0
# Build an image from azure devops pipeline to aws eks

parameters:
- name: succeed
  displayName: Succeed or fail
  type: boolean
  default: false


trigger:
 - main
 - releases/*

pool:
  vmImage: "windows-latest"



stages:
  - stage: init
    jobs:
      - job: init
        continueOnError: false
        steps:
        - task: Docker@2
          inputs:
            containerRegistry: 'docker'
            repository: 'ecr-name'
            command: 'build'
            Dockerfile: '**/Dockerfile'
            tags: 'latest'
          
        - task: ECRPushImage@1
          inputs:
            awsCredentials: 'aws credentilas'
            regionName: 'us-east-1'
            imageSource: 'any-name'
            sourceImageName: 'ecr-name'
            sourceImageTag: 'latest'
            repositoryName: 'ecr-name'
            pushTag: 'latest'
        
-6

Create a repo per application:

aws ecr create-repository --repository-name worker --region us-east-1
aws ecr create-repository --repository-name gateway --region us-east-1

Login to registry

The AWS usr name is fixed for all registry logins

aws ecr get-login-password \
    --region us-east-1 \
| docker login \
    --username AWS \
    --password-stdin <aws_12_digit_account_number>.dkr.ecr.us-east-1.amazonaws.com

Push image

docker build -f Dockerfile -t <123456789012>.dkr.ecr.us-east-1.amazonaws.com/worker:v1.0.0
docker push <123456789012>.dkr.ecr.us-east-1.amazonaws.com/worker:v1.0.0
AAber
  • 1,562
  • 10
  • 14
  • Yeah, but using tags to differentiate your images is crappy way of doing things. – dwjohnston Feb 15 '18 at 22:49
  • Terrible solution, tags are how we version images – Ernani May 31 '18 at 15:36
  • As the above comments suggest, this is an anti-pattern. One that, if used in larger development teams could easily prove to be error prone. You'd be better of scripting a solution. Something like: https://gist.github.com/jmervine/b1835fa3bfcea9eaa9bf2521291f0615 – jmervine Jul 15 '18 at 05:21
  • 4
    @jmervine "better off", not "better of". – Asclepius Oct 17 '19 at 23:06
  • This seems perfectly reasonable for some scenarios. For example, many popular docker repositories use this method to distinguish between "flavors" of an image, e.g. `nginx:alpine` vs `nginx:perl` – jchook Nov 10 '20 at 22:29
  • I updated the procedure, please test and comment. – AAber Jan 29 '21 at 14:21