Docker: How to configure and use a local docker registry

In this article I show you how to create and use your own local docker registry, the reasons to create your own registry are keep images…

Docker: How to configure and use a local docker registry
Photo by Tirza van Dijk on Unsplash

In this article I show you how to create and use your own local docker registry, the reasons to create your own registry are keep images private and have the registry as close to your environment, which can be a huge speed saver if the images are huge, Lets see how we can create our own registry!

What is a docker registry

A Docker registry is a storage and distribution system for named docker images. The same image might have multiple different versions, identified by their tags.

A Docker registry is organized into Docker repositories, where a repository holds all the versions of a specific image. The registry allows Docker users to pull images locally, as well as push new images to the registry (given adequate access permissions when applicable).

By default, the Docker engine interacts with Docker Hub , Docker’s public registry instance. However, it is possible to run on-premise the open-source Docker registry/distribution

Creating a docker compose file with the registry image

Create the following file docker-compose.yml

version: '3' 
services: 
  registry: 
    image: registry:2 
    container_name: registry 
    ports: 
    - "6000:5000" 
    volumes: 
      - /data/docker_registry:/var/lib/registry
  • image: registry:2 is the docker registry image we need
  • in the volumes section we have mount the docker container /var/lib/registry path to the host path /data/docker_registry The reason we do this is to persist after container restarts the images we want to store in our registry

Running the docker compose file

To run the registry container get to the same directory where the docker-compose.yml file is and enter

docker compose up -d

You should see something like the following

[+] Building 0.0s (0/0) 
[+] Running 1/1 
 ✔ Container registry  Started

You can verify that the registry runs using the docker ps command, we can see that the container is up and is binded on port 6000 of our localhost

root@grscript:~/docker/registry# docker ps 
CONTAINER ID   IMAGE                       COMMAND                  CREATED              STATUS          PORTS                                                      NAMES 
1ca24562a093   registry:2                  "/entrypoint.sh /etc…"   About a minute ago   Up 47 seconds   0.0.0.0:6000->5000/tcp                                     registry

Now we need to modify the docker configuration file /etc/docker/daemon.json to make docker aware for the new registry.

{ "insecure-registries": ["localhost:6000"] }

Then you need ro restart docker

systemctl restart docker

How to use the docker registry

To push an image to the docker registry we need this image to exist in local images, this means that we can push to our docker registry an image we downloaded from a public registry or an image we have create/modify. Lets create an image to demonstrate this.

Building an image locally

Save the following file as Dockerfile

FROM python:3.9.13-slim-buster 
 
WORKDIR /hello-world 
COPY ./requirements.txt requirements.txt 
COPY ./app.py app.py 
RUN pip3 install -r requirements.txt 
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

Then create the same directory the following two files

app.py

from flask import Flask 
 
app = Flask(__name__) 
 
@app.route("/") 
def home(): 
    return print("Hello World!") 
 
 
if __name__ == "__main__": 
    app.run(debug=True)

And requirements.txt

flask

This Dockerfile will create an image that will use flask to display a simple “Hello World!” on a web page.

docker build . -t localhost:6000/hello-world
  • localhost6000: is our local registry address

Pushing the local image to the registry

After building the image locally you can push it to the registry by simply entering docker push

docker push localhost:6000/hello-world

if everything goes well you should see the following output

Using default tag: latest 
The push refers to repository [localhost:6000/hello-world] 
66411b6c8c39: Layer already exists 
fc5389353be7: Layer already exists 
7ba4d87fce9c: Layer already exists 
a5aaccb6f0ca: Layer already exists                                                                                                                                              fa7541853d63: Layer already exists 
918b9cb5c3a0: Layer already exists 
2f255e904243: Layer already exists 
1ffc252b74d0: Layer already exists 
56a5c11640c8: Layer already exists 
latest: digest: sha256:34a2d22f70550cc4a59bf19bd139180f991f87c39d2928236b8bc7b9a90955b3 size: 2202

Pulling and running the image from registry

To pull the image from the registry run docker pull

docker pull localhost:6000/hello-world 
 
Using default tag: latest 
latest: Pulling from hello-world 
Digest: sha256:34a2d22f70550cc4a59bf19bd139180f991f87c39d2928236b8bc7b9a90955b3 
Status: Image is up to date for localhost:6000/hello-world:latest 
localhost:6000/hello-world:latest

To run the container enter docker run

docker run localhost:6000/hello-world 
 
 * Debug mode: off 
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. 
 * Running on all addresses (0.0.0.0) 
 * Running on http://127.0.0.1:5000 
 * Running on http://172.17.0.3:5000 
Press CTRL+C to quit

Conclusion

In this article we saw the process of setting a registry and then creating and building an image locally, pushing the image to a registry and pulling and running this image! i hope you enjoyed this article as much i enjoyed writing it!