Docker registry is an open-source application where you can store Docker images. There are some use cases where you don’t want to expose your images publicly but still want to store them in a centralized location. So you can create a private docker registry instead of using Docker Hub. Similarly, in development pipelines, you have to consider network bandwidth, storage usage, and other resources. As a result of using a private docker registry, according to the official docs, you can save more bandwidth, control your application docker image storage, and distribute tightly into your in-house development workflows.
Let’s learn how to set up a private docker registry in Ubuntu using docker-compose.
Prerequisites
- A non-root user with sudo privileges.
- Docker installed PC. Docker installation tutorial.
Installing Docker Compose
Docker-compose allows the user to define how to set up an application in the docker environment using the YAML file named docker-compose.yml. It automates the manual processes of application configuration, including container links and docker volumes.
This command will download the current stable release of Docker Compose.
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Apply executable permissions to the downloaded binary:
$ sudo chmod +x /usr/local/bin/docker-compose
Verify the docker-compose installation.
$ docker-compose --version
OUTPUT docker-compose version 1.25.5, build 8a1c60f6

Docker hub
Configure Docker registry
Let’s create a directory to store docker-compose.yaml file and registry data in your home folder.
$ mkdir -p ~/docker-registry
Create a directory named as data, inside the docker-registry directory to use as docker volume. This directory uses to store docker registry data, including docker images.
$ mkdir -p ~/docker-registry/data
You can configure a private docker registry in 3 different methods.
Create private docker registry with HTTP
you can create a private docker registry with plain HTTP with the following docker-compose file.
version: '3.0' services: registry: container_name: docker-registry restart: always image: registry:2 ports: - 5000:5000 volumes: - data:/var/lib/registry volumes: data: {}
Save this docker-compose.yaml file inside the previously created docker-registry directory. Secondly, you should keep the indentation as above. otherwise, it will output errors. In the registry section, the container name is set as docker-registry and it uses the registry:2 docker image to create the container. The container will be restarted when a server reboots with the “restart: always” option. Moreover, 5000 port of there server is mapped with 5000 port of the container. In the same vein, the data directory has been set as a volume into /var/lib/registry path inside the container, thus you can preserve data in a situation where the container got crashed.
create the docker registry with the following command and the Docker container will be run in the background with the ‘-d‘ option.
$ docker-compose up -d
You can stop containers that are created through docker-compose by the following command.
$ docker-compose down
Since this method creates a plain docker registry without HTTPS, you will come across the following error when trying to pull docker images.
error ... http: server gave HTTP response to HTTPS client
In such cases, add the following content to /etc/docker/daemon.json file of the server where you are trying to pull docker images.
{ "insecure-registries" : ["private-docker-registry-IP/domain:5000"] }
Restart docker service to apply changes.
$ sudo systemctl restart docker
Create private docker registry with SSL/TLS
In addition to the previous method with some extra steps, you can create a secure private docker registry. You need to add a certificate and key pair to enable SSL/TLS with the docker registry.
version: '3.0' services: registry: container_name: docker-registry restart: always image: registry:2 environment: REGISTRY_HTTP_TLS_CERTIFICATE: /certs/certificate.crt REGISTRY_HTTP_TLS_KEY: /certs/certificate.key ports: - 5000:5000 volumes: - data:/var/lib/registry - ./certs:/certs volumes: docker-registry-data: {}
Let’s create certs
directory to store the certificate.
$ mkdir -p ~/docker-registry/certs
You have to create the following openssl.conf file to provide details to generate certificates with openssl
[ req ] distinguished_name = req_distinguished_name x509_extensions = req_ext default_md = sha256 prompt = no encrypt_key = no[ req_distinguished_name ] countryName = "" localityName = "" organizationName = "" organizationalUnitName = "" commonName = "" emailAddress = "" [ req_ext ] subjectAltName = @alt_names [alt_names] DNS = "" IP = ""
IMPORTANT: add a correct domain name or the IP address to the commonName
Run the following command to generate the certificate and key pair valid for 365 days (1 year).
$ openssl req \ -x509 -newkey rsa:4096 -days 365 -config openssl.conf \ -out certs/certificate.crt -keyout certs/certificate.key
Now, run the docker-compose file to start SSL/TLS enabled docker registry container.
$ docker-compose up -d
You can stop containers that are created through docker-compose by the following command.
$ docker-compose down
Create Private docker registry with SSL/TLS enabled and with basic authentication
Let’s create an authentication based docker registry with SSL/TLS. In other words, how to use the username and password-based authentication with a private docker registry. Use the following docker-compose file
version: '3.0' services: registry: container_name: docker-registry restart: always image: registry:2 environment: REGISTRY_HTTP_TLS_CERTIFICATE: /certs/certificate.crt REGISTRY_HTTP_TLS_KEY: /certs/certificate.key REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm ports: - 5000:5000 volumes: - data:/var/lib/registry - ./certs:/certs - ./auth:/auth volumes: data: {}
You have to create an authentication file with the htpasswd tool and it should save in a directory called auth. Let’s create the auth directory and install the htpasswd tool.
$ mkdir -p ~/docker-registry/auth
$ sudo apt-get install apache2-utils -y
Create htpasswd file inside the auth directory with a username and password.
$ htpasswd -bBn registry-user registry-password > ~/docker-registry/auth/htpasswd
Similarly, you can choose any username and password as required.
In conclusion, Start basic authentication enabled the private docker registry by running the following command.
$ docker-compose up -d
You can stop containers that are created through docker-compose by the following command.
$ docker-compose down
since now it has enabled the authentication, you have to log in to the docker registry with the created username and password.
$ docker login host-IP:5000
Read this tutorial to learn more about docker push, docker pull, and other basic commands. Start creating a docker image for your application by referring to this article.
Conclusion
In this tutorial, you got to know how to create a private docker registry with three different methods. You can create your pipelines in the development environment with the use of a private docker registry. Read more about best-practices in creating images here.