Some days it feels almost impossible to keep up in the cloud native world: Kubernetes is deprecating Docker support, Red Hat Enterprise Linux migrated from Docker to Podman, CentOS as we know it is going away and, in its place, comes CentOS Stream. As your head is spinning at the impending change, you continue developing. After all, your business isn’t going to pause while the pieces fall back into place.

To that end, you still need to work. And if your work centers around containers, you depend on images to make it happen. If you use Red Hat Enterprise Linux or CentOS, chances are good you’ve migrated to Podman, a daemonless engine (and Docker alternative) for developing, managing, and running OCI-compliant containers on a Linux system. And if you rely on CentOS, you’re looking at the likelihood of migrating to CentOS Stream. You might also want to host your own image repository. Why? That’s a good question with a fairly simple answer.

As you may know, container (and Kubernetes) security is a hot issue. The problem is the security of such deployments goes all the way up the chain — from the very foundation to the heart of the cluster. But it’s that bottom rung of the chain that can really wreak havoc on your deployments. If you’re using third-party images, you might not know what vulnerabilities they contain. To that end, your best bet is to either only ever use official images (such as those offered by Canonical or other known entities), or building your own.

But if you build your own images, you’ll want to be able to house them locally. Those in-house images might contain proprietary code that you don’t want getting out in the wild.

So how do you host your own image registry? Since your platform is RHEL/CentOS Stream and Podman, you’ve got everything you need to host a local image registry. The one caveat to this is that you won’t be able to access this registry across your LAN. In other words, this local registry is isolated to your dev workstation. The upside of that is it’s even more secure.

Let me show you how this is done. I’ll be demonstrating on CentOS Stream 8. If you are still using CentOS 8, you can either stick with that release or convert it to CentOS Stream. Either way, this will work fine.

Registry vs. Repository vs. Tag

Before we continue on, let’s first understand the difference between a registry, a repository, and a tag. This is actually important to understand, especially if you’re just now getting into the wonderful world of container development.

  • Registry is a service (be it local or third-party) responsible for hosting and distributing images.
  • Repository is a collection of related images. Often such a repository will contain images that provide different versions of the same application or service.
  • Tag is an alphanumeric identifier attached to images within a repository, as a means to differentiate versions of images.

Create the Local Registry

The first step is to create a directory that will house the repository. To do this, log into your CentOS machine and issue the command:

sudo mkdir -p /var/lib/registry

With that directory created it’s time to deploy the local registry. This step is made easy, thanks to Podman. We’ll be using the –privileged flag, which tells the engine to launch the container without any further security constraints and to not add any privilege over what the process launching the containers has.

The command to deploy the registry is:

sudo podman run --privileged -d --name registry -p 5000:5000 -v /var/lib/registry:/var/lib/registry --restart=always registry:2

The above command should launch without complaint.

Now we can configure the Podman registries.conf file such that it knows we have a repository hosted on the local machine. To do this, open the file for editing with the command:

sudo nano /etc/containers/registries.conf

In that file, look for the line:

Change that line to:

What we’ve done is define the registry address as localhost and the port as 5000.

Save and close the file. Restart Podman with the command:

sudo systemctl restart podman

Push Your First Image to the New Registry

We’ll test this out using the tried and true (and official) NGINX image. Of course, if you already have your own images, you can skip the pulling of NGINX and go straight to tagging your own image and pushing it.

But for those who’ve yet to craft their own images, let’s demonstrate with the official NGINX image.

Pull down the NGINX image with the command:

podman pull nginx

Before we push the NGINX image to the registry, we’re going to make some changes to it (so it’s our own image). First, deploy a container based on the newly-downloaded image with the command:

sudo podman run --name nginx-template-base -p 8080:80 -e TERM=xterm -d nginx

Once the container deploys, you’ll be presented with its ID. Access the running container with the command:

sudo podman exec -it CONTAINER_ID bash

Where CONTAINER_ID is the ID of the container given to you when it was initially deployed.

Now we’ll install nano, build-essential, and php with the commands:

apt-get update

apt-get install nano

​apt-get install build-essential

​apt-get install php5

When that completes, exit the container with the command:

exit

Commit the changes to the container (thereby creating a new image) with the command:

sudo podman commit CONTAINER_ID nginx-template

Where CONTAINER_ID is the ID of the container given to you when it was initially deployed.

To see your new image, issue the command:

sudo podman images

You should see a listing for:

localhost/nginx-template

We can now tag the image and push it to the locally hosted registry.

sudo podman tag localhost/nginx-template localhost:5000/nginx-template

Now, if you issue the command:

sudo podman images

You’ll see the nginx-template image listed in the localhost:5000 registry.

Congratulations, you have deployed your own private Podman registry, pulled down an NGINX image, altered that image, tagged the newly altered image, and pushed the new image to your local registry.

Red Hat is a sponsor of The New Stack.