DEV Community

Cover image for We Need to Talk About Docker Registries
Peter Solymos for Analythium

Posted on • Originally published at hosting.analythium.io

We Need to Talk About Docker Registries

By: Peter Solymos

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
Enter fullscreen mode Exit fullscreen mode

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 / © Analythium

Docker architecture / © Analythium

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

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
Enter fullscreen mode Exit fullscreen mode

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

docker load --input alpine-latest.tar
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

docker image remove alpine:latest
docker image remove localhost:5000/my-alpine
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u USER --password-stdin
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Summary

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

Top comments (2)

Collapse
 
derlin profile image
Lucy Linder

Great article! To dig further, I would have talked about OCI compliance (what makes any registry compatible with docker pull/push command).

Also, talking about docker registries, ever heard of github.com/tazjin/nixery? That is a nice twist to the regular registries:

Nixery is a Docker-compatible container registry that is capable of transparently building and serving container images using Nix.

Images are built on-demand based on the image name. Every package that the user intends to include in the image is specified as a path component of the image name.

I found the inner workings very interesting. See community.ops.io/derlin/one-docker... for how to use it.

Collapse
 
raibtoffoletto profile image
Raí B. Toffoletto

Having your own docker registry is super helpful. Kudos for the well written article 🎉