Hosting your own container registry using Podman with SSL encryption on Debian 12 Bookworm
Published at Sep 10, 2023
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
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
Controlling access to rootless Podman for users