Docker Registry is a service used for storing and sharing Docker images. It comes with all sorts of features that are usually behind a paywall or otherwise limited.

In this article, we'll talk about setting up your own Docker Registry on Linux host machine of your choice, step by step - without unneccessary fluff.

The Why

First and foremost, let's discuss the pros and cons of having your own Docker Registry.


  • It can be private, public, or both.
  • There are no inherent access, push, pull, storage, or bandwidth limits.
  • More security, especially when cutting the middleman out of the equation.
  • More resiliency, as you're no longer at the mercy of Docker Hub's availability.


  • Requires extra work.
  • Requires a host machine (a 128MB RAM, 20GB SSD VPS will do just fine 😃).

Getting Started

To have a fully functional and secure Docker Registry, we'll need to download a few packages.

For reference, I'm using Debian 11, and while the installation process might vary, it should work similarly on most distros.

Install Docker & Docker Compose

Docker Registry is an image, which means that in order to use it, we need to have a Docker daemon up and running. We'll also need Docker Compose to simplify the process of configuration.

The following pages will lead you through the process:

Install Apache2-utils

Some distros come with this package pre-installed. You can check whether you have it on by running the following command via terminal: htpasswd.

If it returns the manual for the command, then you can go ahead and skip this step. Otherwise, follow through.

To install this package, run the following commands:

apt update
apt install apache2-utils

Setting Up

Now that we're up to speed - we can go ahead and set it up. Follow through the steps below.

Create the Folder Structure

This step is not necessary, but the next steps will assume you didn't skip it - as it helps keep the structure clean.

Navigate to the path of your choice and run the following commands:

mkdir ./docker-registry
mkdir ./docker-registry/auth

It's advised to store all related files inside that folder.

Generate the .htpasswd File

Htpasswd is an easy-to-use authentication method. We'll need a simple encrypted .htpasswd file that stores our username and password.

To generate the aforementioned file, run the following command and proceed through the prompts:

htpasswd -c -B <file> <user>

Replace as follows:

  • <file>: path to store the generated file
  • <user>: name of the user

Create docker-compose.yml File

Run the following command:

touch docker-compose.yml

Then open the generated file with your favorite editor and paste the following YAML code:

version: '3.9'

    container_name: docker-registry
    image: registry:2
      - ./auth:/auth:ro
	    - "5000:5000"
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: My Docker Registry  Realm

The following defines a docker-registry container, which will mount the auth folder you previously created (including .htpasswd) and use it during authentication.

Running the Container

You can now run your container using the following command:

docker compose -p "docker-registry" -up -d

The registry should now be available under port 5000, which you can verify by running the following command and going through the prompts:

docker login localhost:5000

It will ask you for your username and password, both of which you defined during the generation of the .htpasswd file.

If it's working fine, you should be getting the greeting message. But the fact that it asks you for username and password is an indicator in itself.

Using the Registry

Now that we have our registry up and running, we can use it to its full extent. Below, you can find crucial information on consuming your service.

First and Foremost: Sign In

Start by signing in to your service using the following command:

docker login <ip address|domain>:5000

Proper Image Naming

Docker images use the following format for names:


These should be replaced as follows:

  • <registry>: IP address or the domain where we're hosting the registry
  • <image>: name of the image
    e.g., my-app
  • <tag>: tag of the image
    e.g., latest

For example, the image of this website's frontend app is named as follows:

Push and Pull

All Docker functionality works just like for any other registry and requires no additional work.

Simply run:

docker push
docker pull

Final Thoughts

Image registry is a fairly simple yet powerful concept that will allow you to leverage the power of containers on your own terms. You are no longer constrained by third-party commercial solutions.