Create a Private Registry

Andre Rocha
2 min readNov 7, 2022


A private registry can be useful for storing container images for your applications in an internal, controlled (and potentially more secure) infrastructure.

In this article I will show you how to create a secure and SSL/TLS ready private registry that can be used to store containers in general, as well as integrate with Red Hat OpenShift, to be able to perform disconnected deployments.


We will need the following requisites:

  • FQDN:
  • OS: RHEL8.6+
  • SELinux: Enforcing
  • Firewalld: Enabled
  • Registry: Podman
  • Apache Tools
  • Volume: 100Gb mounted on /data


Create required directories:

[root@registry ~]# mkdir -p /data/registry/{auth,certs,data}

Generate certificates for the Container registry. In this example, we are creating certificates that are valid for 10 years.

[root@registry ~]# openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /data/registry/certs/ -x509 -days 3650 -out /data/registry/certs/ \
-subj "/C=US/ST=NorthCarolina/L=Raleigh/O=Red Hat/OU=Engineering/" \
-addext "subjectAltName ="

Copy the generated certificate to the anchors trusted directory, and run update-ca-trust:

[root@registry ~]# cp /data/registry/certs/ /etc/pki/ca-trust/source/anchors/
[root@registry ~]# update-ca-trust

Generate an authentication file for the Image Registry:

[root@registry ~]# dnf -y install httpd-tools
[root@registry ~]# htpasswd -bBc /data/registry/auth/htpasswd registry redhat12345678

Generate a random secret:

[root@registry ~]# date | md5sum
10f207a4cbba51bf00755b5a50718966 -

Create the container registry using the image

[root@registry ~]# dnf -y install podman
[root@registry ~]# podman create --name ocp-registry --net host -p 5000:5000 \
-v /data/registry/data:/var/lib/registry:z -v /data/registry/auth:/auth:z \
-e "REGISTRY_HTTP_SECRET=10f207a4cbba51bf00755b5a50718966" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /data/registry/certs:/certs:z \

The above command will generate messages like this:

Trying to pull
Getting image source signatures
Copying blob fd4a5435f342 done
Copying blob 213ec9aee27d done
Copying blob 4583459ba037 done
Copying blob b136d5c19b1d done
Copying blob 6f6a6c5733af done
Copying config dcb3d42c17 done
Writing manifest to image destination
Storing signatures
Port mappings have been discarded as one of the Host, Container, Pod, and None network modes are in use

Create a UNIT file for your registry, to automatically start the container at boot.

[root@registry ~]# cat /etc/systemd/system/ocp-registry.service
Description=OCP Registry
ExecStart=/usr/bin/podman start -a ocp-registry
ExecStop=/usr/bin/podman stop -t 10 ocp-registry

Start the container:

[root@registry ~]# systemctl daemon-reload 
[root@registry ~]# systemctl enable --now ocp-registry.service
Private Registry Running
Private Registry Running

Allow TCP 5000 port on Firewalld:

[root@registry ~]# firewall-cmd --permanent --add-port=5000/tcp
[root@registry ~]# firewall-cmd --reload

Ensure authentication and SSL/TLS trusted is working:

[root@registry ~]# curl -u 'registry:redhat12345678'{"repositories":[]}

Generate a temporary file with the authentication information for OpenShift disconnected installs:

[root@registry ~]# cat <<EOF > ~/registry-secret.json
"": {
"email": "",
"auth": "$(echo -n 'registry:redhat12345678' | base64 -w0)"

That’s it. Now your new private registry is up and running. Have fun!



Andre Rocha

I'm just a SysAdmin with some experience in OpenSource, DevOps and Datacenter Services, who likes to share knowledge.