Running your own Docker Registry on Ubuntu

A few days I ago, I saw a tweet from the Official Docker Account on about how to run your own Docker Registry.

In this tutorial I want to extend the idea further, and show you how to run it with Docker Compose as well, on Ubuntu Server.

What I want to show you, is similar to how I run my own Docker Registry to host the images of my side project ChessDuo.

This is all for fun, if you are running your own business, I strongly recommend to use some managed service to host your images, like AWS ECR, which was not contributing much to the bill of my previous employer. But if you want to run your own Docker Registry, then fasten your seatbelt.

Installing Docker on your Ubuntu Server

In case Docker was not already installed on your Ubuntu, here are the instructions quickly to install it. They also include removing any old Docker versions installed on the System.

sudo apt-get remove docker docker-engine docker.io containerd runc docker-compose
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install apt-transport-https ca-certificates curl gnupg
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Then add the current user to the docker group, to get permissions to access the Docker Daemon.

sudo groupadd docker
sudo usermod -aG docker ${USER}

You can validate your setup by running this command

docker version
which should print the server version of your Docker daemon.

Preparing the Docker Registry Setup

Docker Compose file

Our setup will consist of an Nginx container, that is directing the traffic to the actual Docker Registry container. Nginx itself will handle the authentication, but we will not run it using SSL in this post. We can cover that in the future instead.

Let's start by making the necessary folders

mkdir -p docker-registry/auth
cd docker-registry

Now inside the docker-registry let's create the Docker Compose file docker-compose.yml, and fill it with the content in this url

Nginx htpasswd file

Now let's generate the auth/nginx.htpasswd, that contains the credentials needed to login to the Docker Registry. In our example, we will have the username admin and the password test.

sudo apt install apache2-utils
htpasswd -cbB auth/nginx.htpasswd admin test

Nginx Config file

Now create the Nginx config file auth/nginx.conf, with the following from this url

Feel free of course to customize the hostname of your virtual server. Change it from localhost to anything else you suits your setup.

Running your Docker Registry

Now that we have prepared everything, let's start our Docker Registry, and test it.

docker-compose up -d

the -d flag here is necessary to detach the starting containers. You can validate your setup by running the command docker ps. You should see two running containers like this

0ee50afd9bb8        nginx:alpine          "/docker-entrypoint.…"   3 months ago        Up 3 months         80/tcp, 0.0.0.0:5043->443/tcp   root_nginx_1
a8af1b5d28d4        registry:2            "/entrypoint.sh /etc…"   3 months ago        Up 3 months         127.0.0.1:5000->5000/tcp        root_registry_1

but of course, not 3 months ago :D

To use our Docker Registry, we need to login. We can use the docker login command

docker login localhost:5043
Enter your admin and test credentials.

Now let's pull some images from the Official Docker Registry, tag them and push them to our registry

docker pull nginx
docker tag nginx localhost:5043/my_registry_nginx
docker push localhost:5043/my_registry_nginx

Congrats. You just hosted your own Docker Registry.

These are some commands that can help you to query your own Docker Registry

curl http://admin:test@localhost:5043/v2/_catalog

it should output something like this

{"repositories":["my_registry_nginx"]}

and this endpoint to list all the tags that belong to some repo.

curl http://admin:test@localhost:5043/v2/my_registry_nginx/tags/list

{"name":"my_registry_nginx","tags":["latest"]}

I hope you found this post helpful. Feel free to reach out to me on Twitter. @OmarQunsul.

References