We Need to Talk About Docker Registries

Peter Solymos
Peter Solymos
We Need to Talk About Docker Registries
Photo by Jason Leung / Unsplash
Table of Contents
Table of Contents

A Docker registry stores Docker images, this is where we push images to and pull images from. Why do we need a registry? What registries are out there? How can we work with them? Read on to find out.

Many Docker tutorials begin with docker pull as the first command to cover. The docker pull command is followed by the "tag" of a Docker image that we want to be pulled. Say that we wanted the latest Alpine Linux image (I picked this due to its minimal size):

docker pull alpine:latest

# latest: Pulling from library/alpine
# 530afca65e2e: Pull complete
# Digest: sha256:7580ece7963bfa...
# Status: Downloaded newer image for alpine:latest
# docker.io/library/alpine:latest

But where does this image come from?

What is a Docker registry?

Where does the Docker command line interface (CLI for short) pulls the images from? The answer is on the last line of the output. docker.io is the URL for a so called Docker registry. In this case, it refers to the default registry, Docker Hub, applied when you don't specify a registry URL as part of the pull command.

Docker Hub is a service provided by Docker for finding and sharing container images.

The registry URL is usually followed by the user or organization ID, the repository name, the image name and the tag: <registry>/<user>/<repository>/<image>:<tag>.

In short, a Docker registry stores Docker images. This is where we push images to and pull images from:

Docker architecture
Docker architecture / © Analythium

Read more about how the different parts of the Docker system relate to each other in this introductory post:

Docker Basics for Data Apps
Docker is the most popular virtualization environment to deliver software in containers. In this post we review the basics of working with Docker to lay the foundation for “dockerizing” data applications.

Why do you need a registry?

You might think that you only need a registry because you need to pull your parent images (like Ubuntu, Alpine, r-base from the Rocker project etc.) from somewhere. Then you can build your Docker images locally using a Dockerfile, and run them. Why bother with a registry at all?

You can even use the docker save and docker load commands to save to a compressed tar file:

docker pull alpine:latest

docker save -o alpine-latest.tar alpine:latest

ls -sh alpine-latest.tar
# 11368 alpine-latest.tar

Then take this tar file, copy it to another server and load it:

docker load --input alpine-latest.tar

now imagine that you are managing more than two servers, or you want to share the Docker image with others (to use it or to serve as a parent image). The save/copy/load workflow becomes cumbersome.

In this case, using a registry might be a much better idea. Luckily, there are many options to choose from, and you can even host your own registry.

Roll your own registry

If you want a registry hosted on your machine, just pull the registry image. The next command will pull the registry image, and run the similarly named container in the background on port 5000:

docker run -d \
  -p 5000:5000 \
  --restart=always \
  --name registry registry:2

Tag the Alpine image with the URL of your local registry, localhost:5000, and push the image:

docker tag alpine:latest localhost:5000/my-alpine

docker push localhost:5000/my-alpine

Remove the images so the docker images will not list these anymore:

docker image remove alpine:latest
docker image remove localhost:5000/my-alpine

Pull the image from the local registry and list it with docker images to verify that it is there again:

docker pull localhost:5000/my-alpine

Stop and remove the registry container. The -v option makes sure to remove anonymous volumes associated with the container which is often used to mount a volume from your hard drive into the container where the images are stored:

docker container stop registry && \
  docker container rm -v registry

If you want your own registry to be accessed over a network, then you need to think about security and access control.

Setting up transport layer security (TLS) for HTTPS and user authentication are all advanced topics, so implement those at your own risk.

For now, we will continue with a hosted registry, as most people do.

Log into a registry

When you work with private registries or private images, you need to log in with the docker login command. For Docker Hub, just type docker login. For  all other registries, type in the registry URL as well, e.g. docker login ghcr.io.

The Docker CLI then will prompt you for your username and password (or access token).

You can log in programmatically by providing your username and the password through standard input:

echo $CR_PAT | docker login ghcr.io -u USER --password-stdin

As an alternative, the password can be provided via a file, this approach won't leave trace of your token in your history:

cat ~/my_password.txt | docker login -u USER --password-stdin

Use one of these approaches to log into any public or private repository for which you have credentials. The credentials will be stored locally: in $HOME/.docker/config.json on Linux or %USERPROFILE%/.docker/config.json on Windows. After login, there is no need to re-authenticate until you log out with docker logout.

Note that docker login requires users to use sudo or be root in most cases.

It is always a good idea to use a token instead of your password. Tokens can have limited scope (i.e. only for pulling images), and can be revoked at any time without it impacting other areas of your life.

Commonly used registries

There are many registries out there besides Docker Hub. Here is a non-exhaustive list of options.

GitHub container registry (the ghcr.io URL from above) is available as part of GitHub Packages for free and paid plans, even for private repositories under the free plan. This registry requires authentication using your GitHub token.

An alternative to GitHub is GitLab (registry.gitlab.com), which has provided registry support for its free (public and private) repositories long before GitHub. The docs are also much better in my opinion, and the whole experience is tightly integrated with GitLab's CICD pipelines. This registry also needs login with a token.

Heroku comes with a Docker registry (registry.heroku.com) where the Docker-based deploys push the images to.

Of course, every major cloud provider offers a Docker container registry that is often integrated with their other offerings. Latency should be minimal due to network proximity to the servers:

Other common alternatives for container registries, Helm charts, etc., include:

Although these services are called "container registry", but strictly speaking they store container images.


We reviewed what container registries are, how to access them, and what are the commonly used services out there that you can leverage for your workflow.

You have now a good understanding of where the images go after push and where the images come from after pull.

Further readings

Great! Next, complete checkout for full access to Hosting Data Apps
Welcome back! You've successfully signed in
You've successfully subscribed to Hosting Data Apps
Success! Your account is fully activated, you now have access to all content
Success! Your billing info has been updated
Your billing was not updated