Docker registries: a roundup

Docker registries: a roundup

In this post, we will do a roundup of all the popular docker registries available in the market.

One of the main components in a production devops workflow is the docker registry. The humble docker registry sits somewhere in your CI/CD pipeline. It does a simple job of storing and retrieval of different versions of your container images, more like your own private container image warehouse.

The obvious way to get started with a docker registry is to use dockerhub, Docker’s official public facing registry. For consuming existing public images from dockerhub, you don’t even need any sort of authentication. But for publishing your own images, you need to signup and create a free account there.

Why you need a private registry

When you want to build and publish container images which can only be accessed by your team or organization or customers, you should be using a private container registry. There are other reasons to use a private registry. You can setup fine-grained access control if you use a private registry. You can also introduce custom workflows like scanning your image for vulnerabilities.

How a docker registry works

You only need 3 docker related commands to interact with a Docker registry. The “docker login” which authenticates you with the registry. For public-facing images/registries, you can skip this part. Then comes the “docker pull ” which pulls the said image from the registry. It assumes you’ve already authenticated with the registry before pulling images from it. Finally, you have the “docker push ” which will push your image to the registry.

Docker registry
Docker registry

You can connect your registry to other services like your CI pipeline, a Kubernetes/OpenShift cluster etc. to your registry to push or pull images.

your own hosted registry

A quick way to get a taste of a private repository is to host your own docker registry on a VM. Docker provides an official image. You front it with an Nginx server and you can have a private registry running in minutes. This will give you a secure registry with authentication. You can check out how this is done in detail here.

Once you login, you can easily push and pull images from the registry.

docker login https://<server-where-registry-is-hosted>.com

# build and tag your image
docker tag test-image:v1.0 <server-where-registry-is-hosted>.com/test-image:v1.0

# push it to registry
docker push <server-where-registry-is-hosted>.com/test-image:v1.0

# pull from registry
docker pull <server-where-registry-is-hosted>.com/test-image:v1.0

Gitlab registry

If you are using Gitlab to host your version control, they have an excellent built-in registry which you can use for free. You can authenticate into the account using your Gitlab private token.

Gitlab private token
Gitlab private token
# login to gitlab registry
docker login registry.gitlab.com

# build a tagged image
docker build -t registry.gitlab.com/<group-name>/<project-name>/myapp:1.0 .

# push it to gitlab registry
docker push registry.gitlab.com/<group-name>/<project-name>/myapp:1.0

You can access your Gitlab registry via UI in Gitlab’s console.

Gitlab container registry
Gitlab container registry

Other options

docker registries as a service

Dockerbub offers a paid plan where you can run private repositories. Quay.io offers something similar as well. One thing I find unique about Quay.io is, it has this feature where you just specify the Dockerfile and quay will build it in their premises. I’m not sure if other services offer this feature.

open source add-ons

There is also an industry-standard open source registry with nice UI, called Harbor.

Harbor container registry
Harbor container registry

If you are specific about access control, you can try out another open source project Portus which fronts a plain docker registry with authorization, UI and a REST API.

Both Portus and Harbor offer security scanning of container images.

Registries in the big 3 of the cloud

Now we enter the realm of using registries provided by major cloud providers.

Amazon ECR

Assuming you have the AWS cli installed and configured, you can create a new repository using the following command,

$ aws ecr create-repository --repository-name myproject
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:us-east-1:123456789120:repository/myproject",
        "registryId": "123456789120",
        "repositoryName": "myproject",
        "repositoryUri": "123456789120.dkr.ecr.us-east-1.amazonaws.com/myproject",
        "createdAt": 1553269154.0
    }
}

To login to your registry,

$ aws ecr get-login --no-include-email
docker login -u AWS -p RandomMonkeysTypyingOnKeyboards123== https://123456789120.dkr.ecr.us-east-1.amazonaws.com

You paste the ensuing command into your shell again to login. Once you login, you can do the usual pulling and pushing of images like this:

# tag
docker tag hello-world 123456789120.dkr.ecr.us-east-1.amazonaws.com/myproject:1.0

# push
docker push 123456789120.dkr.ecr.us-east-1.amazonaws.com/myproject:1.0

# pull
docker pull 123456789120.dkr.ecr.us-east-1.amazonaws.com/myproject:1.0

Azure container registry

These steps assume that you already have the Azure CLI installed and a valid Azure subscription.

You first create a resource group.

$ az group create --name myproject --location eastus
{
  "id": "/subscriptions/xxxxxxxx-yyyy-zzzz-1234-aabbaabababc/resourceGroups/myproject",
  "location": "eastus",
  "managedBy": null,
  "name": "myproject",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": null
}

Followed by a command to create a registry.

$ az acr create --resource-group myproject --name myapps --sku Basic
{
  "adminUserEnabled": false,
  "creationDate": "2019-03-22T16:33:16.441160+00:00",
  "id": "/subscriptions/xxxxxxxx-yyyy-zzzz-1234-aabbaabababc/resourceGroups/myproject/providers/Microsoft.ContainerRegistry/registries/myapps",
  "location": "eastus",
  "loginServer": "myapps.azurecr.io",
  "name": "myapps",
  "networkRuleSet": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "myproject",
  "sku": {
    "name": "Basic",
    "tier": "Basic"
  },
  "status": null,
  "storageAccount": null,
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries"
}

Unlike AWS, you can login to Azure registry using azure cli command.

az acr login --name myapps

To push and pull docker images,

# tag image
docker tag hello-world myapps.azurecr.io/hello-world:v1

# push image
docker push myapps.azurecr.io/hello-world:v1

# pull image
docker pull myapps.azurecr.io/hello-world:v1

Google container registry

The prerequisite for Google container registry is to have container registry API enabled for your project. Once you do that and have the Gcloud SDK installed on your system, you can configure authentication for your registry.

gcloud auth configure-docker

To push and pull container images,

# tag
docker tag hello-world gcr.io/<project-id>/hello-world:v1

# push
docker push gcr.io/<project-id>/hello-world:v1

# pull
docker pull gcr.io/<project-id>/hello-world:v1

Best practices for docker registries

Irrespective of what registry you use, there are some universal best practices which will make your life easier.

Use ACL

The right kind of access control goes a long way in protecting and maintaining your container images. You can sort them by teams/namespaces, and some tools like Portus have audit logs to see what activity has transpired in your registry. All registries have some kind of access control which can be leveraged.

Scanning for vulnerabilities

Some registries have an image vulnerability analysis. This will be done when images are pushed into the registry. There are also vendors who specialize in this sort of service, like Twistlock, which provides additional features like compliance checks.

Geo-replication

If you are a power user of your registry, then it makes a lot of sense to:

  1. Locate your registry images in the same region as your app deployments.
  2. Replicate your registry across multiple regions if you have multi-region deployments.

DigitalOcean has a nice article about the latter and how they achieved it for their docker registry. Again, this feature is present in most production level docker registries in the market.

AWS Azure docker GCP