Docker with Amazon ECR

TL;DR; If you are using Amazon EC2 Container Registry for your Docker images, you are probably aware that you have to use Docker login for the registry via the Amazon Web Services (AWS) Command Line Interface (CLI) utility. This implies that you have to install and configure the AWS CLI and its dependency (Python), however, there are alternatives that do not require installing the AWS CLI.

Background

The Amazon EC2 Container Registry (Amazon ECR) became generally available in 2015. It was a welcome addition to the Amazon Web Services product set, as it allowed AWS customers to host private container registries. The general goal behind Amazon ECR was to simplify development and production workflows. For me, this goal was successfully accomplished, with one caveat: I have to install and run additional tools on my machine, tools I otherwise not need. One such tool is the AWS CLI utility. While the AWS CLI is great and indispensable for those who live and breathe Amazon EC2, there may be cases when not everyone needs this utility or perhaps should not have a CLI access level. This is especially true for larger organizations.

Assuming I have Docker installed if I ran docker pull without first logging into the ECR Docker registry, I will get the following :

$docker pull my-aws-account.dkr.ecr.us-west-2.amazonaws.com/foo:latest
Pulling repository my-aws-account.dkr.ecr.us-west-2.amazonaws.com/foo:latest
unauthorized: authentication required

In order to obtain the Docker login, I must first install and configure the AWS CLI utility, which in turn per the AWS CLI user guide,  requires first installing Python 2 version 2.6.5+ or Python 3 version 3.3+.

Even with the AWS CLI installed, I have to make sure that the version of CLI plays well with Docker version to avoid:

“Unknown options: –no-include-email”

After the AWS CLI is installed and configured, using the Docker against Amazon ECR is pretty straightforward and no different from other container registries, with an occasional login refresh (depending on your security configuration):
eval $(aws ecr get-login --region my-region)

AWS CLI in Docker

To avoid installing AWS CLI on my machine, the next best thing is to run the AWS CLI inside the Docker container. Quite a few publicly available AWS CLI docker images are available on dockerhub.com, but for one reason or another, none of them exactly satisfied my needs (I’m picky), so I did what everybody else does: created my own illya/aws-cli.

FROM python:2.7-slim
ENV VERSION=1.11.136
RUN apt-get update \
 && apt-get install -y --no-install-recommends \
 && apt-get install --reinstall groff-base \
 && mkdir -p /aws \
    && pip install -U pip \
    && pip install awscli==${VERSION} \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /aws
ENTRYPOINT ["aws"]

With this image, if I need to get the Docker login, all I have to do is run:

eval $(docker run --rm -v $HOME/.aws:/root/.aws:ro illya/aws-cli ecr get-login --region us-west-2)

Moreover, this image supports all AWS CLI subcommands available for a given CLI version:

docker run --rm -v $HOME/.aws:/root/.aws:ro aws-cli ec2 describe-vpcs --region=us-east-1

I can even use it to configure the AWS CLI credentials for my machine. For more examples and details please refer to README.md

Amazon ECR Docker Credential Helper

AWS Labs released ECR Credentials Helper (written in Go), which seamlessly integrates with the Docker daemon and makes it easier to use Amazon ECR by leveraging Docker’s Credential Helper Protocol.

The Credential Helper does require a couple of things:

  • Golang 1.6+
  • Docker 1.11+

Golang

Per golang.org – “Go is an open source programming language that makes it easy to build simple, reliable, and efficient software”. If you’ve never tried it, you totally should. Installing Go itself is simple and it is very straightforward follow the Install the Go tools from the Golang Getting Started documentation page.

Docker

If you are running a Docker version earlier than 1.11, you should probably upgrade it, regardless of ECR.

Configuration

I followed the instructions from the repository README.md to install and configure my $HOME/.docker/config against two AWS regions: [us-east-1] and [us-west-2], which ended up looking like this:

{
  "credsStore": "ecr-login",
  "credHelpers": {
    "my-aws-account.dkr.ecr.us-west-2.amazonaws.com": "ecr-login",
    "my-aws-account.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"
  }
}

To verify that I don’t have afoo image in my local Docker registry:

docker images my-aws-account.dkr.ecr.us-west-2.amazonaws.com/foo:latest
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

Now, the moment of truth:

docker pull my-aws-account.dkr.ecr.us-west-2.amazonaws.com/foo:latest
latest: Pulling from foo
9e1d18812a0d: Already exists
f49ebe34919a: Already exists
...
451b4fbc9616: Pull complete
361b5c020933: Pull complete
Digest: sha256:86df90592794c3f8d54d2c6969863abeef3b1d66bed603a6b90847b3198b7feb
Status: Downloaded newer image for my-aws-account.dkr.ecr.us-west-2.amazonaws.com/foo:latest

I can pull (and push if permitted) Docker images from the Amazon ECR without having to run thedocker login command, and by implication, without having to install the AWS CLI solely for Docker login purposes.

I hope you find this information helpful. Please let me know if you find any inaccuracies and/or if you have any questions or comments.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s