My goal is to have a docker registry running on a raspberry pi (behind the rpi
hostname), me being able to push images from my linux PC on the same network. I’m following this guide: https://docs.docker.com/registry/insecure/#use-self-signed-certificates
I did the following steps on my rpi:
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -addext "subjectAltName = DNS:rpi" -x509 -days 365 -out certs/domain.crt
docker run -d --restart=always --name registry -v $HOME/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -p 443:443 registry
Steps on my PC:
scp pi@rpi:certs/domain.crt ca.crt
sudo mkdir -p /etc/docker/certs.d/rpi:5000/
sudo mv ca.crt /etc/docker/certs.d/rpi:5000/
Now, when I try pushing an image docker push rpi:5000/test-image
, it fails with the following:
Get "https://rpi:5000/v2/": dialing rpi:5000 with direct connection: connecting to 192.168.1.201:5000: dial tcp 192.168.1.201:5000: connect: connection refused
If I tag the image with the 443 port docker push rpi:443/test-image
I get this error: Get "https://rpi:443/v2/": x509: certificate is valid for 227b7008fe5910b8b4b0563bb8ebcb9e.708221ab4c2f3a622587d123822b2328.traefik.default, not rpi
How to push docker images to a remote using self-signed certificates?
2
Answers
Another software running on my raspberry pi (
k3s
) took over the 443 port.docker push
first makes a request to https://rpi.home/v2/ and validates the certificate, which is normally served by theregistry
container. However, ifk3s
server is running, it serves the/v2
url and provides a completely different certificate.The solution was to map a different port to 443 of the container.
It appears that you are listening on port 443. For this to work, you need to change a few things:
rpi.localdomain
. If there’s no domain in the beginning of the image path, and no port (which you don’t need for 443), then it’s treated as a username on Docker Hub./etc/docker/certs.d/rpi:5000/
but/etc/docker/certs.d/rpi.localdomain/
or whatever the domain name is. Putting it in a directory named 5000 but connecting to 443 means it wasn’t used.For step 4, here’s an example of my own script for setting up certs:
In the above script, the
ca.pem
is what gets copied to/etc/docker/certs.d/${registry}/ca.crt
.