80

So I'm new to ecs/ecr, but it seems like I have to name (with a tag) the image after the repository name in order to push that image to the repository.

So my question is: Is it intended that the user (me) would ONLY be pushing a single image and any associated versions of that image to a single repository in ecr, thus creating ANOTHER repository if i need to push a completely different image?

basically, one repo for nginx, one repo for postgressql, etc.

Ankit
  • 45
  • 1
  • 7
aphexlog
  • 1,503
  • 3
  • 16
  • 43

3 Answers3

48

Yes. And also, possibly, no.

You push images to ECR. How you configure your image is up to you. Ideally, you'd have an image with a single responsibility, but this is your decision.

If you have multiple images, you push to multiple ECRs. If you have a single image doing many things, you can get away with a single ECR.

You can also push multiple images to the same ECR with creative use of tags (e.g. having the "image name or flavour" in the tag using your own naming convention.

Community
  • 1
  • 1
MrDuk
  • 16,578
  • 18
  • 74
  • 133
  • 6
    You push images, you dont push containers - see https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html – gmsharky Aug 17 '18 at 12:28
  • 14
    It is a bit weird having to create a repository for each image. what if I have say 100 microservices, each has its own image, do I end up with 100 repos? – A.Rashad Mar 23 '22 at 22:45
  • @A.Rashad We had the same issue, see my solution below. – lxg Sep 01 '22 at 17:11
  • Please distinguish between Elastic Container Registry (ECR) and an ECR Repository within the registry. "you push to multiple ECRs" would be better worded: "you push to multiple ECR repositories' – markmnl Jul 07 '23 at 07:07
11
  1. It is recommended to push images with the version number of the same type.

For example your-repo:1.1, your-repo:1.2

If you push images with the same that exist in the ECR repository than your old image will be replaced with the new image you are pushing.

  1. It depends on how your application is working. It is always advised to separate container working logically separate.

For example The database image with a persistence volume. So, If a database container dies than it would not affect your data.

mohit
  • 2,325
  • 23
  • 48
6

In our case, we wanted to have one repository for all our services, because otherwise we would have to create and maintain ECR infrastructure for each single service.

What we did was basically creating one shared repository for all services (Cloudformation in this case):

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  registryName:
    Type: String
    Default: services

Resources:
  ecr:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: !Ref registryName
      ImageTagMutability: MUTABLE

… and then when building the services, we would use SERVICENAME_VERSION as the convention for the actual image/version:

#!/bin/bash

set -e

export AWS_ACCOUNT="123456789000"
export AWS_DEFAULT_REGION="eu-central-1"
export SERVICE_NAME="demo-service"
export SERVICE_VERSION="${SERVICE_VERSION:-latest}"
export IMAGE_NAME="$AWS_ACCOUNT.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/services:${SERVICE_NAME}_${SERVICE_VERSION}"

aws ecr get-login-password | docker login --username AWS --password-stdin "$AWS_ACCOUNT.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
docker build -t $IMAGE_NAME .
docker push $IMAGE_NAME

(Simplified, but works.)

UPDATE:

In a real-world example, when you want to pull images into an ECS cluster that is placed in a VPC, you will need to set up VPC endpoints on the ECR. The Cloudformation code for this looks something like this:

  privateLinkEcrApi:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api"
      PrivateDnsEnabled: true
      VpcId: !ImportValue vpc
      SecurityGroupIds:
        - !ImportValue albSecurityGroup
      SubnetIds:
        - !ImportValue publicSubnetA
        - !ImportValue publicSubnetB
      VpcEndpointType: Interface

  privateLinkEcrDkr:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr"
      PrivateDnsEnabled: true
      VpcId: !ImportValue vpc
      SecurityGroupIds:
        - !ImportValue albSecurityGroup
      SubnetIds:
        - !ImportValue publicSubnetA
        - !ImportValue publicSubnetB
      VpcEndpointType: Interface

  privateLinkEcrLogs:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
      PrivateDnsEnabled: true
      VpcId: !ImportValue vpc
      SecurityGroupIds:
        - !ImportValue albSecurityGroup
      SubnetIds:
        - !ImportValue publicSubnetA
        - !ImportValue publicSubnetB
      VpcEndpointType: Interface

  privateLinkEcrS3:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcId: !ImportValue vpc
      SecurityGroupIds:
        - !ImportValue albSecurityGroup
      SubnetIds:
        - !ImportValue publicSubnetA
        - !ImportValue publicSubnetB
      VpcEndpointType: Interface

  privateLinkEcrS3Gw:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcId: !ImportValue vpc
      RouteTableIds:
        - !ImportValue publicRouteTable
        - !ImportValue privateRouteTableA
        - !ImportValue privateRouteTableB
      VpcEndpointType: Gateway

(NB: You will have to adapt this code as the actual VPC, subnets etc. are set up in a different template, and the actual configuration depends very much on your own environment. But this should get you on the right track.)

lxg
  • 12,375
  • 12
  • 51
  • 73
  • Is this because your ECS cluster does not have access to a nat and internet gateway? https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/networking-outbound.html This confuses me because AFAIK private ECR is accessible from anywhere. I see no mention of it being only accessible in the VPC: https://docs.aws.amazon.com/AmazonECR/latest/userguide/images.html – runamok May 10 '23 at 18:07
  • Good question, to be honest I don’t remember. However, the ECS cluster was on Fargate in this case and behind an ALB. – lxg May 11 '23 at 05:34