Create a Private Registry

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.

Requisites

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

Installation

[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/registry.rhbrlabs.com.key -x509 -days 3650 -out /data/registry/certs/registry.rhbrlabs.com.crt \
-subj "/C=US/ST=NorthCarolina/L=Raleigh/O=Red Hat/OU=Engineering/CN=registry.rhbrlabs.com" \
-addext "subjectAltName = DNS:registry.rhbrlabs.com"

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

[root@registry ~]# cp /data/registry/certs/registry.rhbrlabs.com.crt /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 docker.io/library/registry:2

[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_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry" \
-e "REGISTRY_HTTP_SECRET=10f207a4cbba51bf00755b5a50718966" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /data/registry/certs:/certs:z \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.rhbrlabs.com.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.rhbrlabs.com.key docker.io/library/registry:2

The above command will generate messages like this:

Trying to pull docker.io/library/registry:2...
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
22633f37262a4ab2d64fc8beb44bb80618b11802974fb2f45d31d98db3cf14e8

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

[root@registry ~]# cat /etc/systemd/system/ocp-registry.service
[Unit]
Description=OCP Registry
[Service]
Restart=always
ExecStart=/usr/bin/podman start -a ocp-registry
ExecStop=/usr/bin/podman stop -t 10 ocp-registry
[Install]
WantedBy=network-online.target

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' https://registry.rhbrlabs.com:5000/v2/_catalog{"repositories":[]}

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

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

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

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andre Rocha

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