Error response from daemon: Get https://192.168.2.22:5000/v2/: x509: cannot validate certificate for 192.168.2.22 because it doesn't contain any IP SANs http: TLS handshake error from 192.168.2.22:38696: remote error: tls: bad certificateTo fix this error: add your IP address under the section v3_ca
$ sudo vi /etc/ssl/openssl.cnf
[ v3_ca ] subjectAltName = IP:192.168.2.22
$ mkdir ~/registry $ cd ~/registry/Generate certificate:
$ openssl req -x509 -nodes -sha256 -newkey rsa:4096 \ -keyout registry.key -out registry.crt \ -days 14 -subj '/CN=192.168.2.22'
$ ls -1 ~/registry
registry.crt registry.keyCopy certificate into /etc/docker/certs.d/ directory:
$ sudo mkdir -p "/etc/docker/certs.d/192.168.2.22:5000" $ sudo cp ~/registry/registry.crt "/etc/docker/certs.d/192.168.2.22:5000"Restart Docker:
$ sudo systemctl restart docker
$ cd ~/registry/Create htpasswd with username/password: admin/admin:
$ docker container run --rm --entrypoint htpasswd registry:2.7.0 -Bbn admin admin > htpasswd
$ cat ~/registry/htpasswd
admin:$2y$05$ICkq3vbj0hkj3sqV/R.dkOrnvLHyR/JDmD7fhNCBP3WHpZTWqRed6
$ vi ~/registry/config.yml
version: 0.1 log: accesslog: disabled: false level: info fields: service: registry environment: development storage: filesystem: rootdirectory: /var/lib/registry delete: enabled: true cache: blobdescriptor: inmemory auth: htpasswd: realm: class-realm path: /etc/docker/registry/htpasswd http: addr: 0.0.0.0:5000 host: https://192.168.2.22:5000 secret: asecretforlocaldevelopment tls: certificate: /etc/docker/registry/certs/registry.crt key: /etc/docker/registry/certs/registry.key debug: addr: 0.0.0.0:5001
$ vi ~/registry/Dockerfile
FROM registry:2.7.1 ADD config.yml /etc/docker/registry/config.yml ADD registry.crt /etc/docker/registry/certs/registry.crt ADD registry.key /etc/docker/registry/certs/registry.key ADD htpasswd /etc/docker/registry/htpasswd
$ ls -1 ~/registry
config.yml Dockerfile htpasswd registry.crt registry.keyBuild registry:
$ DOCKER_BUILDKIT=0 docker build -t local-registry .
Sending build context to Docker daemon 11.26kB Step 1/5 : FROM registry:2.7.1 2.7.1: Pulling from library/registry ... Digest: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d Status: Downloaded newer image for registry:2.7.1 ---> 2d4f4b5309b1 Step 2/5 : ADD config.yml /etc/docker/registry/config.yml ---> 845a8d18a3b5 Step 3/5 : ADD registry.crt /etc/docker/registry/certs/registry.crt ---> 87b386161c5b Step 4/5 : ADD registry.key /etc/docker/registry/certs/registry.key ---> 545e56e52c62 Step 5/5 : ADD htpasswd /etc/docker/registry/htpasswd ---> 682f3dd78080 Successfully built 682f3dd78080 Successfully tagged local-registry:latest
$ docker container run -d -p 5000:5000 --name registry local-registry
4619b37683cd272f2daf43b47877bfe03d01c216db5436d21fcaa5c4526a9634
$ docker container ls --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a948cd767c54312925313fb4fa120af5e7d5097bc5ca8bcf3646f7d5a22c61eb local-registry "/entrypoint.sh /etc/docker/registry/config.yml" 43 seconds ago Up 42 seconds 0.0.0.0:5000->5000/tcp registry
$ docker login 192.168.2.22:5000
Username: admin Password: admin WARNING! Your password will be stored unencrypted in $HOME/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login SucceededVerify ~/.docker/config.json:
$ cat ~/.docker/config.json
{ "auths": { "192.168.2.22:5000": { "auth": "YWRtaW46YWRtaW4=" } }, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.12 (linux)" } }The aude value is base64 encoded. To decode it:
$ echo "YWRtaW46YWRtaW4=" | base64 --decode
admin:admin
$ docker logout 192.168.2.22:5000
Removing login credentials for 192.168.2.22:5000Verify that credentials were removed from ~/.docker/config.json:
$ cat ~/.docker/config.json
{ "auths": {}, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.12 (linux)" } }
$ docker image tag alpine:latest 192.168.2.22:5000/alpine:latestList images:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE 192.168.2.22:5000/alpine latest a24bb4013296 8 weeks ago 5.57MB alpine latest a24bb4013296 8 weeks ago 5.57MBPush the image to registry:
$ docker image push 192.168.2.22:5000/alpine:latest
The push refers to repository [192.168.2.22:5000/alpine] 50644c29ef5a: Pushed latest: digest: sha256:a15790640a6690aa1730c38cf0a440e2aa44aaca9b0e8931a9f2b0d7cc90fd65 size: 528If you get the following error, then you are probably not logged in to the registry (see above):
The push refers to repository [192.168.2.22:5000/alpine] 50644c29ef5a: Preparing no basic auth credentials
$ docker image pull 192.168.2.22:5000/alpine:latest
latest: Pulling from alpine Digest: sha256:a15790640a6690aa1730c38cf0a440e2aa44aaca9b0e8931a9f2b0d7cc90fd65 Status: Downloaded newer image for 192.168.2.22:5000/alpine:latest 192.168.2.22:5000/alpine:latestIf you get the following error, then you are probably not logged in to the registry (see above):
Error response from daemon: Get https://192.168.2.22:5000/v2/alpine/manifests/latest: no basic auth credentialsNotes:
docker image pull alpine@sha256:abcxz
.$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a948cd767c54 local-registry "/entrypoint.sh /etc/docker/registry/config.yml" 43 seconds ago Up 42 seconds 0.0.0.0:5000->5000/tcp registryList repositories:
$ docker container exec -it a948cd767c54 /bin/sh
/ # ls -1 /var/lib/registry/docker/registry/v2/repositories/ alpineVerify the registry configuration:
$ docker container exec -it a948cd767c54 /bin/sh
/ # ls -1R /etc/docker/registry/ /etc/docker/registry/: certs config.yml htpasswd /etc/docker/registry/certs: registry.crt registry.key
$ curl -u admin:admin -i -k https://192.168.2.22:5000/v2/
HTTP/2 200 content-type: application/json; charset=utf-8 docker-distribution-api-version: registry/2.0 {}List repositories:
$ curl -u admin:admin -i -k https://192.168.2.22:5000/v2/_catalog
HTTP/2 200 content-type: application/json; charset=utf-8 docker-distribution-api-version: registry/2.0 {"repositories":["alpine"]}Note the option -k with the curl command. It's used to suppress this certificate error:
curl: (60) SSL certificate problem: self signed certificate