Docker Hub and Docker Registries: A Beginner’s Guide

The usage of Docker Hub — Docker’s official container registry — has been skyrocketing. From November 2019 to the end of July 2020, total pulls (a pull is a download of a Docker image) from Docker Hub grew from 130 billion to 242 billion. This is another indicator of just how popular containerization in general and Docker in particular have become.

It’s no secret that Docker is everywhere. But understanding the specifics of the ecosystem can be challenging. What exactly is a container registry? What benefits does using Docker Hub offer?  Here, we’ll help you answer those questions and provide you with a step-by-step example of how you can get started with Docker’s official registry, Docker Hub.

What is a Docker Registry?

A Docker registry is a service that hosts and distributes Docker images

In many cases, a registry will consist of multiple repositories which contain images related to a specific project. Within a given repository tags are used to differentiate between versions of an image (e.g. ubuntu/httpd:version2.4, ubuntu/httpd:version2.5, ubuntu/httpd:version2.6 where “version2.x” is the tag). Users can pull (download) images they want to use or push (upload) images they want to store in a registry.

By providing a centralized source for images, registries can help enable tighter version control and make it easier to manage and distribute images. Additionally, many registry services will offer additional features that help automate build and deployment processes and improve security.

Docker registries can be hosted in the cloud or on-premises. In addition to Docker Hub, other popular examples of Docker registries include:

You can even spin up your own Docker registry from the official registry image, but generally it’s worth exploring alternatives before using this basic image as a starting point.

What is Docker Hub?

Docker Hub is Docker’s official cloud-based registry for Docker images.

As you might expect, since Docker Hub is Docker’s official registry, it is the default registry when you install Docker. It hosts over 100,000 images including official images for MongoDB, nginx, Apache, Ubuntu, and MySQL that have all been downloaded over a billion times each.

In addition to the public repositories that anyone can pull from, Docker Hub offers private repositories where individuals or teams can host images they wish to restrict access to. Docker Hub also offers features such as GitHub and Bitbucket integrations that help automate development build processes and support for webhooks which can act as triggers for everything from automated tests to notifications.

Why use Docker Hub?

So, with all the different Docker registry options, why should you use Docker Hub? Here are a few of the key upsides of Docker Hub:

  • A large library of trusted images — Docker Certified images, Verified Publisher images (which are Docker Certified and verified by the publisher), and Official Images published by Docker add a layer of trust for users. With millions — or in some cases billions — of downloads for many commonly used images, you can count on a reliable base image when you use Docker hub. While that’s great from the user perspective, it also benefits publishers as hosting an image in Docker Hub can give your project more exposure.
  • A free tier — Currently, Docker’s free plan offers unlimited public repositories and 1 private repository with up to 3 collaborators. This is useful for basic testing to get you familiar with the platform. However, recent changes to the terms of service make it unsuitable for serious development.
  • Built-in security features — All accounts can benefit from local image vulnerability scans. “Team” accounts also gain access to audit-logs and multifactor authentication (MFA) to further secure repositories.
  • Integrations & features that enable CI/CD — Docker Hub also supports GitHub & Bitbucket integrations, automated tests, build triggers, and webhooks to help automate development pipelines and enable CI/CD (continuous integration/continuous delivery).

Of course, there’s never a one-size-fits-all solution, so Docker Hub won’t be the right answer for every use case. For example, if you need to store images on-premises to reduce latency or for data sovereignty reasons. In that case, a cloud-platform like Docker Hub isn’t the right answer. Alternatively, you may need to cache images locally to reduce latency or bandwidth consumption.

How to use Docker Hub: A crash course

Now that you understand what Docker Hub is, let’s walk through basic usage. Here, we’ll demonstrate how to pull an image from Docker Hub to your local machine, and then push a version with a tag back to your own repository.

If you want to follow along, you’ll need a Docker Hub account. If you don’t have an account, you can sign-up here. You’ll also need to install Docker.

Step 1: Create your repository

Once you have a Docker Hub account, you can create a repository in just a few clicks at https://hub.docker.com/repositories.

First, click Create Repository

create repository button on docker hub

 Give your repository a name and description, select if you want it to be public or private, and then click Create.

naming your repository

 

Step 2: Pull a Docker image from Docker Hub

You could create your own image if you prefer, but for the sake of this tutorial, we’ll pull the “Hello World” image.

We’ll start by logging into our Docker account from our terminal with the sudo docker login -u <username> command:

johnnyo@LAPTOP-5V55HON5:~$ sudo docker login -u username

Password:

WARNING! Your password will be stored unencrypted in /home/johnnyo/.docker/config.json.

Configure a credential helper to remove this warning.

Login Succeeded

johnnyo@LAPTOP-5V55HON5:~$

Notice the credential warning we received. For the sake of this demo, we’ll ignore it, but we recommend securing your credentials for production use!

Next, we’ll pull the “Hello World” Docker image with the docker pull hello-world command.

johnnyo@LAPTOP-5V55HON5:~$ sudo docker pull hello-world

Using default tag: latest

latest: Pulling from library/hello-world

0e03bdcc26d7: Pull complete                                                                                             Digest: sha256:8c5aeeb6a5f3ba4883347d3747a7249f491766ca1caa47e5da5dfcf6b9b717c0

Status: Downloaded newer image for hello-world:latest

docker.io/library/hello-world:latest

johnnyo@LAPTOP-5V55HON5:~$

Step 3: Push an image to your private repository

Now that we have the “Hello World” image, let’s copy it with a new name before we send it to our private repository. We’ll do that with the command docker tag <current image name>  <our user name>/<new image name>[:tag]. We’ll use the docker images command to list our images before and after so we can see the change.

johnnyo@LAPTOP-5V55HON5:~$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

hello-world         latest              bf756fb1ae65        9 months ago        13.3kB

johnnyo@LAPTOP-5V55HON5:~$ sudo docker tag hello-world ourusername/johnnyodemo:v1.1.1.1

johnnyo@LAPTOP-5V55HON5:~$ sudo docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE

hello-world                   latest              bf756fb1ae65        9 months ago        13.3kB

ourusername/johnnyodemo   v1.1.1.1            bf756fb1ae65        9 months ago        13.3kB

johnnyo@LAPTOP-5V55HON5:~$johnnyo@LAPTOP-5V55HON5:~$

Changing an image name does NOT change the contents of the image. While this particular change is arbitrary, the key takeaway is we can push local images to Docker Hub. This holds true for ANY of your local Docker images.

Now, we can push the image to our private repository with the command docker push <our user name>/<new image name>[:tag].

johnnyo@LAPTOP-5V55HON5:~$ sudo docker push ourusername/johnnyodemo:v1.1.1.1

The push refers to repository [docker.io/ ourusername /johnnyodemo]

9c27e219663c: Layer already exists                                                                                      v1.1.1.1: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 size: 525

johnnyo@LAPTOP-5V55HON5:~$

 

Going back to our Docker Hub account, we can see the new tag is stored in our private repository.

tag updated on docker hub

 

How to proxy Docker Hub with JFrog Container Registry

We mentioned earlier that Docker Hub free tier can limit development. One of the main reasons for this is rate limiting on pushes and pulls. Caching images outside of Docker Hub can allow you to overcome these limits. As a result, finding the right Docker Hub proxy and caching solution — on-premises or in the cloud — can go a long way. You’ll be able to get the upside of Docker Hub (a wealth of trusted images) while avoiding the rate limiting that can hamstring CI/CD workflows.

Here, we will walk through how to set up JFrog Container Registry to proxy Docker Hub, allowing you to cache frequently accessed images. We’ll use the cloud-platform for this example, but you can spin up JFrog on premises for free as well.

Pro-tip: For a deeper dive on configuration of JFrog Container Registry or any other JFrog platform topic, we recommend reading the documentation.

Step 1: Create your free trial

Navigate to this link and create your free trial, no credit card required:

Input your username, password, etc. You will be sent an email to validate your account, click the link to complete your registration.

Note: We recommend picking a server location that is geographically close to your location.

Once you get to the confirmation screen, login, and proceed to step 2.

Step 2: Navigate to the remote repositories section

Once you’re logged into your new account, click Administration → Repositories → Repositories

User-added image

Step 3: Create a new remote repository

Click Remote → + New Remote Repository

User-added image

Click on the Docker icon in the SELECT PACKAGE TYPE popup.

User-added image

On the Basic tab input your Repository Key and for the URL use this for Docker Hub: https://registry-1.docker.io/

User-added image

 For this basic example, we can leave everything else as defaults. If you would like to associate your Docker Hub account so your push/pull requests to Docker Hub will be authenticated, you can do so on the Advanced tab.

When you’re done, click Save & Finish.

Step 4: Login to your newly created account and pull an image

From your Docker CLI, execute the command docker login <your_server>.jfrog.io and input your password. Here is an example using the account “johnnyo”:

johnnyo@LAPTOP-5V55HON5:~$ sudo docker login johnnyo.jfrog.io

Username: johnnyo@example.com

Password:

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Configure a credential helper to remove this warning. See

https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

johnnyo@LAPTOP-5V55HON5:~$

Next, pull an image like you would from Docker hub, but prepend it with a URL in the format of <your_server>.jfrog.io/your_repository/. We will pull the current Ubuntu image here, so we’ll use: <your_server>.jfrog.io/your_repository/ubuntu. For example, to get the latest Ubuntu image with our “johnnyo” server and “johnnyo” repository:

johnnyo@LAPTOP-5V55HON5:~$ sudo docker pull johnnyo.jfrog.io/johnnyo/ubuntu

Using default tag: latest

latest: Pulling from johnnyo/ubuntu

Digest: sha256:fff16eea1a8ae92867721d90c59a75652ea66d29c05294e6e2f898704bdb8cf1

Status: Downloaded newer image for johnnyo.jfrog.io/johnnyo/ubuntu:latest

techchicago6400.jfrog.io/techchicago6400/ubuntu:latest

johnnyo@LAPTOP-5V55HON5:~$

We can now see that the image is downloaded locally:

johnnyo@LAPTOP-5V55HON5:~$ sudo docker images

[sudo] password for johnnyo:

REPOSITORY                                        TAG             IMAGE ID        CREATED         SIZE

johnnyo.jfrog.io/johnnyo/ubuntu   latest          d70eaf7277ea    2 days ago      72.9MB

hello-world                                       latest              bf756fb1ae65    9 months ago    13.3kB

johnnyo@LAPTOP-5V55HON5:~$

More importantly, we can also look back in our JFrog account and see the image is also cached there! We’ve successfully cached the image for future use.

User-added image

Final thoughts: Next steps with Docker Hub

To summarize what we’ve covered here:

  • Docker registries are used to host and distribute Docker Images
  • Docker Hub is Docker’s official cloud-based registry
  • To get started with Docker Hub you can pull (download) an image or push (upload) one of your local images
  • Finding the right on-premises or cloud-based Docker registry — like JFrog Container Registry – can help optimize how Docker Hub fits into your development pipeline

Of course, these are just the basics. Where containerization gets interesting is in the projects you build and development pipelines you create to support them. With Docker Hub you have an excellent resource to help you source useful base images to build from and a variety of tools to streamline your collaboration, testing, and CI/CD processes.