Running my Docker Registry

This article is a narration of me finally crossing another thing off my to-do list. A Docker Registry is quite similar to a Git Server - it's useful to store and version Docker images. You are probably familiar with DockerHub, which is one of the most used registries out there.

Well, I work play with Kubernetes quite a lot, so use a lot of Docker images. Of course, I could use DockerHub, but in the end, it's much more convenient to be using a Docker Registry which I host. Plus, I'm hosting it! That's reason enough in my books :)
In my typical fashion, I'm going the extra mile to run it in Kubernetes on my K3S cluster!

To start, there's a registry image over on DockerHub, which allows me to very easily run my own Docker Registry. Bottom line, all I need is that image, run it with the appropriate volumes attached for persistent storage, create a user, and expose the appropriate ports.

With this plan in mind, I can get building each block. Of course, I start with a template using the command kubectl create deployment docker-registry --image registry:2 -o yaml > manifest.yaml which sets us up with a template deployment manifest.

Most of the heavy lifting has been done so far, really convenient!
I know the registry uses port 5000, so I'll add this to the container specs.
ports: - containerPort: 5000
Afterwards, the environment variables.

As you can see from above, I have 2 folders, /auth and /registry-data. /auth will hold the credentials for the users for the registry, while registry-data will hold all the images pushed to it. This brings us to the next bit.

The next building block is possibly the most crucial. All this data I am putting on the registry cannot be volatile - in other words, it has to be persistent in the event the pod is deleted. Here comes the persistent volume claims.

I have 2 PVCs here, one of which will store the docker images, and the other holding the registration data. The latter probably doesn't need an entire gigabyte but I have a good amount of space and it's better to have more than not enough. The next part is to specify where to mount these PVCs

  containers:
  - image: registry
    imagePullPolicy: Always
    name: docker-registry
    volumeMounts:
      - name: docker-reg-pvc
        mountPath: /registry-data
      - name: docker-auth-pvc
        mountPath: /auth
    ports:
      - containerPort: 5000
  volumes:
    - name: docker-reg-pvc
      persistentVolumeClaim:
        claimName: docker-reg-pvc
    - name: docker-auth-pvc
      persistentVolumeClaim:
        claimName: docker-auth-pvc

Now, I just need to make sure I can access the registry. This leads to a very standard service using my LoadBalancer. On top of this, I make a new DNS entry in my PiHole so that registry.alexbissessur.dev goes to my Docker Registry. This is only for my local network and is simply to avoid me remembering the IP address.

At this stage, practically everything is done. The last thing is to go into Longhorn, mount the auth volume on a node, and run htpasswd -Bc registry.password alex to generate the account I will use with the registry.

If everything works now, I can login to the docker then push or pull my images. One final addition would be to add these credentials to a secrets file so I don't get errors when trying to use these images in Kubernetes.