How to create a private Docker Registry on Ubuntu 16.04

Private Docker repository

The official Docker registry has a large collection of images available for your use as a base for your own. Contributing to the repository is nearly as simple as pulling from it, but what do you do when you have images that should be kept private? You create a private registry hosted locally.

Docker provides a registry image purposely built for hosting private registries. You simply pull the image and start it — easy as pie. Of course, in production environments there a quite a few settings that require consideration.

Local

Create the Local Repository

Running a registry for proof-of-concept or where security isn’t a concern is pretty straightforward. You simply download and run the Docker Registry image.

  1. Download and install the latest version of Docker.
  2. Pull the Docker registry image
    docker pull registry
  3. Run a registry container. For example, we’ll run it with the name registrydev.
    docker run -d -p 5000:5000 --restart=always -n registrydev registry:2

Push Images to the Local Repository

You will need a source image to tag. For this example, we are going to pull down the ubuntu:16.04 image from the public docker repository. Alternatively, you could build your own image to start with.

docker pull ubuntu:16.04

Now we’ll tag it for our local repository.

docker tag ubuntu:16.04 localhost:5000/myubuntu:16.04

With the image tagged we can push it to our repository.

docker push localhost:5000/myubuntu:16.04

Pull Images from the Local Repository

Pulling down from your local repository is nearly identical to pulling from Docker’s official repository. The only difference is we need to specify our repository’s hostname and port, which is exactly how our image was tagged to begin with. To pull our myubuntu:16.04 image from our repository, we would run the following command

docker pull localhost:5000/myubuntu:16.04

Production Environments

Storage

Having appropriate storage is essential to running a Docker registry. You want to be assured that your images are protected from corruption or disaster. After all, you may need to retrieve the previous version for audit or rollback reasons.

We’ll configure a volume to map into our Registry container. The volume itself should be mounted on redundant storage, such as a RAID5, RAID6 or RAID10, for example.

Create the directory where images will be stored:

mkdir -p /data/docker

Start the registry. The following command will mount /data/docker as /var/lib/registry in the container, and it will tell the registry to listen on port 5000 of all network interfaces. We could narrow that down to one particular interface, if needed.

docker run -d -p 5000:5000 --restart=always -n registry -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 registry:2

We can verify that our container is running using docker ps

docker ps

The output will look something like the following.

Output of docker ps showing the registry
docker ps registry prod

Pushing Images to Our Production Registry

With our registry up and running we are ready to start pushing images to it. In order to push an image to the registry, we must tag the image with our registry’s hostname. The hostname of the registry will be the hostname of the server hosting the container.

Tagging an image uses the following syntax.

docker tag source-image registry-server:port/name:tag

For example, if we are tagging an image called ubuntu:16.04 for our registry hosted at myregistry.com:5000, we would tag the ubuntu:16:04 image as follows:

docker tag ubuntu:16.04 myregistry.com:5000/ubuntu:16.04

With our image tagged we can now push it to our registry.

docker push myregistry.com:5000/ubuntu:16.04