
Private Docker Registry
(on Debian8)
A Docker registry in the repository of images your created or downloaded. Registry may be public or private. If you using docker in your organisation you’ll definitely want your images to be secured. So, it’s time to deploy your own private docker registry.
Let’s start with the initial conditions. This private docker registry example based on 2 hosts:
- 1st is docker registry (192.168.56.102) OS: Debian 8
- 2nd is docker test (192.168.56.101) OS: Debian 8
# Docker Engine
First of all we need docker engine to be installed on your private docker registry host (192.168.56.102)
1 2 3 4 5 |
sudo apt-get install -y apt-transport-https ca-certificates sudo echo 'deb https://apt.dockerproject.org/repo debian-jessie main' > /etc/apt/sources.list.d/docker.list sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D sudo apt-get update sudo apt-get install -y docker-engine |
after all we can check docker
1 2 3 4 5 |
root@docker-server:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@docker-server:~# docker images REPOSITORY TAG IMAGE ID CREATED SIZE root@docker-server:~# |
# Docker Compose
We also will need docker-compose
1 2 |
curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose |
# Docker Registry
Firstly, we’ll create directories to store images, certs and auth file. I like all the docker data to be placed in the custom directory /data. I often mount separate disk to /data volume
1 2 3 4 |
mkdir -p /data/docker_registry_images mkdir -p /data/docker_registry_certs mkdir -p /data/docker_registry_auth mkdir -p /data/docker_registry_compose |
Create user with password
https://docs.docker.com/registry/deploying/#/restricting-access
1 2 |
docker run --name docker_auth_container --entrypoint htpasswd registry:2 -Bbn dockeruser dockerpassword > /data/docker_registry_auth/htpasswd docker rm docker_auth_container |
Create certificates
https://docs.docker.com/registry/insecure/
You can create self-signed certificate or use letsencrypt(https://letsencrypt.org/) if you have a domain name registered.
Next steps are shown for those who are playing with IP as a docker private registry name
on the 192.168.56.102(registy server)
edit /etc/ssl/openssl.cnf
and add after ‘[ v3_ca ]’ next:
subjectAltName = IP:192.168.2.102
example:
1 2 3 4 |
... [ v3_ca ] subjectAltName = IP:192.168.1.102 ... |
Let’s create sertificates:
1 2 |
cd /data/docker_registry_certs openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt |
WARNING!!
You can leave everything by default EXCEPT the line
Common Name (e.g. server FQDN or YOUR name) []:192.168.56.102:5000
1 2 3 4 |
sudo mkdir -p /etc/docker/certs.d/192.168.56.102:5000 sudo chmod -R 700 /etc/docker/certs.d/192.168.56.102:5000 sudo cp domain.crt /etc/docker/certs.d/192.168.56.102:5000/ca.crt ls -l /etc/docker/certs.d/192.168.56.102:5000 |
NOTE!!!
You will need to copy your domain.crt to all servers and put it right to
1 |
/etc/docker/certs.d/192.168.56.102\:5000/ca.crt |
Otherwise you will have an error at login:
1 |
'Error response from daemon: Get https://192.168.56.102:5000/v1/users/: x509: cannot validate certificate for 192.168.56.102 because it doesn't contain any IP SANs' error |
Create file /data/docker_registry_compose/docker-compose.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
registry: restart: always image: registry:2 ports: - 5000:5000 environment: REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt REGISTRY_HTTP_TLS_KEY: /certs/domain.key REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm volumes: - /data/docker_registry_images:/var/lib/registry - /data/docker_registry_certs:/certs - /data/docker_registry_auth:/auth |
Starting docker private registry:
1 2 |
cd /data/docker_registry_compose/ docker-compose up -d |
My output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@docker-server:/data/docker_registry_compose# docker-compose up -d Pulling registry (registry:2)... 2: Pulling from library/registry e110a4a17941: Pull complete 2ee5ed28ffa7: Pull complete d1562c23a8aa: Pull complete 06ba8e23299f: Pull complete 802d2a9c64e8: Pull complete Digest: sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d Status: Downloaded newer image for registry:2 Creating dockerregistrycompose_registry_1 root@docker-server:/data/docker_registry_compose# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a644c789ccb9 registry:2 "/entrypoint.sh /etc/" 8 seconds ago Up 6 seconds 0.0.0.0:5000->5000/tcp dockerregistrycompose_registry_1 root@docker-server:/data/docker_registry_compose# |
Try it! Checking on the test host(NOT DOCKER REGISTRY)
Console:
1 2 3 4 |
root@debian8_2:/# docker login https://192.168.56.102:5000 Username: dockeruser Password: Login Succeeded |
Web:
1 |
curl -k -u dockeruser:dockerpassword https://192.168.56.102:5000/v2/_catalog |
# Playing with registry
1 2 3 4 5 6 7 8 9 10 11 12 13 |
root@debian8_2:/# docker pull ubuntu && docker tag ubuntu 192.168.56.102:5000/ubuntu Using default tag: latest latest: Pulling from library/ubuntu 43db9dbdcb30: Pull complete 2dc64e8f8d4f: Pull complete 670a583e1b50: Pull complete 183b0bfcd10e: Pull complete Digest: sha256:c6674c44c6439673bf56536c1a15916639c47ea04c3d6296c5df938add67b54b Status: Downloaded newer image for ubuntu:latest root@debian8_2:/# docker push 192.168.56.102:5000/ubuntu root@debian8_2:/# curl -k -u dockeruser:dockerpassword https://192.168.56.102:5000/v2/_catalog {"repositories":["ubuntu"]} |
Good luck, have fun! No drama 🙂
Useful links:
https://github.com/docker/distribution/issues/948
https://docs.docker.com/registry/insecure/
https://docs.docker.com/engine/security/https/
https://docs.docker.com/engine/tutorials/dockerimages/