Hosting your own container registry using Podman with SSL encryption on Debian 12 Bookworm

Published at Sep 10, 2023

#debian#administration#podman#hosting#container

TL;DR

Welcome back to the IT companies essentials. We are having our own git instance by hosting forgejo. But as you realized we are handling a lot of containers. So, what about having our own container repository — like a Git for containers? This way, we can manage the applications of our company that we are packaging in containers much better. After finishing the tutorial you will have your own container registry up and running.

Why

A Git repository instance was good for developing code. But in production we frequently need containers to deploy our products.

We need to make our own custom containers and maintain their lifecycle as well as updates, and versions. For this we need something like a Git repository for containers.

We could use Dockerhub, but maybe we will have to pay for it sooner or later, or there is some attack on it. It is thus better to have our own registry, too and use public ones, in addition to our local repository.

System maintenance

Install dependencies and necessary packages


sudo apt-get update && sudo apt-get install apache2-utils

First create the necessary directories and add credentials (choose your own). Replace the respective placeholder of course.
sudo mkdir -p /opt/registry/{auth,certs,data}
sudo chown your_username:your_username -R /opt/registry/*
htpasswd -bBc /opt/registry/auth/htpasswd registryuser 
registryuserpassword
openssl req -newkey rsa:4096 -nodes -keyout domain.key 
-x509 -days 365 -out domain.crt -subj "/CN=domain" -addext 
"subjectAltName = DNS:domain"
mv domain.key domain.crt /opt/registry/certs/
sudo cp /opt/registry/certs/domain.crt 
/usr/local/share/ca-certificates/
sudo update-ca-certificates

Starting the registry container

Now, pull the container


podman run --name myregistry 
-p 5000:5000 
-v /opt/registry/data:/var/lib/registry:z 
-v /opt/registry/auth:/auth:z 
-e "REGISTRY_AUTH=htpasswd" 
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" 
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd 
-v /opt/registry/certs:/certs:z 
-e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt" 
-e "REGISTRY_HTTP_TLS_KEY=/certs/domain.key" 
-e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true 
-d 
docker.io/library/registry:latest

Test the connection


curl -v -k https://your_domain:5000
Adding your podman container to systemd

podman generate systemd --new --name myregistry -f
mkdir -p ~/.config/systemd/user/
mv -v "container-myregistry.service" ~/.config/systemd/user/


systemctl --user daemon-reload
systemctl --user enable container-myregistry
systemctl --user start container-myregistry
systemctl --user status container-myregistry
Then avoid having to login as the user

sudo loginctl enable-linger user_name

And that’s it for deploying the instance.

Dealing with old SSL Versions and other errors

I could start a major discussion again, why it is not suspicious at all that setting up the registry is so complicated, but I just will tell your how to circumvent the problems.

During the development I encountered three major problems

  • Missing CA verification for the certificate
  • Wrong TLS version number and enforcement of deprecated certificate formats
  • Apple TextEdit automatically ruining deploy commands
The solution to the second problem is rather easy and I already provided the correct command above. The third problem is solved by using another text editor or LibreOffice.

Fix: x509: certificate signed by unknown authority docker registry

This fix is done on your local machine, not on the remote:


sudo nano /etc/containers/registries.conf```
<br>
And add
```bash
[registries.insecure]
registries=['your_domain:5000'] #nohttps

You could also deploy your own CA-authority and sign the certificate.

Another way is to login as follows


podman login yourdomain:5000 --tls-verify=false

Use the registry in Podman

Authenticate


podman login <hostname>:5000 --authfile <pull secret file>
podman logout <hostname>:5000
podman login <hostname>:5000

Push a container ubi8 with ubi8 latest


podman pull registry.access.redhat.com/ubi8/ubi:latest
podman login <registry hostname>:<port>
podman tag registry.access.redhat.com/ubi8/ubi:latest 
<registry>
hostname>:<port>/ubi8/ubi:latest
podman push <registry hostname>:<port>/ubi8/ubi:latest

And that’s it, you now can handle your own container development cycles.

Thank you for reading, and I hope you found the article useful. Subscribe to my newsletter and hack on until you are free :-)

Join my email list 9k+ and people to learn more about the good lifestyle, technology, and money.

Helpful Ressources

Configuring a registry How to implement a simple personal/private Linux container image registry for internal use

Add sel-signed certificates

Controlling access to rootless Podman for users

Running rootless Podman as a non-root user

Podman and insecure registries