SUMMARY:
A. Making a Docker Registry on a host machine and Pulling from that same registry.
B. Pulling a Docker Registry from a registry of another host machine (1st method: insecurely)
C. Pulling a Docker Registry from a registry of another host machine (2nd method: securely)
WHAT is DOCKER PRIVATE REGISTRY (LOCAL / REMOTE SERVER)?
Firstly, we will make a private registry storing our docker image either in local or remote server.
Secondly, we will make a certificate for this registry with openssl.
A) Making a Docker Registry on a host machine and Pulling from that same registry.
A registry is a storage and content delivery system in a host machine, holding secured Docker images (you can know the storage path later below), and can be available in different tagged versions.
A registry is a storage and content delivery system in a host machine, holding secured Docker images (you can know the storage path later below), and can be available in different tagged versions.
1. Create a container with registry docker image (this will download registry image from hub.docker.com)
docker container run --name local_registry -d -p 5000:5000 registry
why 5000? because docker registry is running at port 5000.
2. Check if the container is running:
docker ps -a / docker container ls
Access the container on 5000 port with your serverip ( system's IP) http://<serverip>:5000/v2/_catalog
on CLI: curl localhost:5000/v2/_catalog
on browser: just paste and change to localhost:5000/v2/_catalog
you will not be able to do this unless in vagrant file, you add in this line:
config.vm.network "forwarded_port", guest: 5000, host: 5000
3. Inspect the container (cause we are interested in the Mounts) docker container inspect local_registry

4. check the source by typing ls then the highlighted above. this will show blank.
for my case: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data
Access the container on 5000 port with your serverip ( system's IP) http://<serverip>:5000/v2/_catalog
on CLI: curl localhost:5000/v2/_catalog
on browser: just paste and change to localhost:5000/v2/_catalog
you will not be able to do this unless in vagrant file, you add in this line:
config.vm.network "forwarded_port", guest: 5000, host: 5000
3. Inspect the container (cause we are interested in the Mounts) docker container inspect local_registry

4. check the source by typing ls then the highlighted above. this will show blank.
for my case: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data
it will show here:
/var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data/docker/registry/v2/repositories/myalpine#
5. Clone the ubuntu image to localhost:5000/ubuntu:latest
docker image tag localhost:5000/myalpine
OR
docker image tag ubuntu 127.0.0.1:5000/myalpine
notice how this is different from ifanrahman/hisalpine:latest? this is because the ifanrahman one is to push to docker hub. but localhost is to push to private registry.
6. Push the image to docker registry
OR
docker image tag ubuntu 127.0.0.1:5000/myalpine
notice how this is different from ifanrahman/hisalpine:latest? this is because the ifanrahman one is to push to docker hub. but localhost is to push to private registry.
6. Push the image to docker registry
docker image push localhost:5000/myalpine
can check here: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data/docker/registry/v2/repositories/myalpine#
7. then delete the image
docker rmi localhost:5000/myalpine
8. Pull the image from the local/private registry with following command
docker image pull localhost:5000/myalpine
can check here: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data/docker/registry/v2/repositories/myalpine#
7. then delete the image
docker rmi localhost:5000/myalpine
8. Pull the image from the local/private registry with following command
docker image pull localhost:5000/myalpine
B) Pulling a Docker Registry from a registry of another host machine (1st method: insecurely)
Consideration for this example
IP address of registry server is 192.168.33.10
1. Tag the docker image (alpine) with 192.168.33.10:5000
IF you haven't pull alpine, follow below. if yes skip:
1) remove all the containers
docker rm -f $(docker ps -a -q)
2) pull the docker image alpine ( you can take any image)
docker pull alpine
2. tag the image with private IP address of Registry server
docker image tag alpine 192.168.33.10:5000/prvalpine
3. verify the tagged docker image got created
docker images
4. create Docker registry container (if you haven't create it)
docker container run -d -p 5000:5000 --name local_registry registry
5. push the tagged docker image (it will throw an error because the repository is not secure)
docker push 192.168.33.10:5000/prvalpine
Error:-> Get https://192.168.33.10:5000/v2/: http: server gave HTTP response to HTTPS client
Remedy: If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Remember to change your IP as per your docker host system IP)
{
"insecure-registries": ["192.168.33.10:5000"]
}
6. restart the Docker daemon
systemctl restart docker
7. start the Docker registry Container (cause once you restart, containers will be exited)
docker start local_registry
8. push the tagged image (this time it should be pushed to docker registry without any error)
docker push 192.168.33.10:5000/prvalpine
2) pull the docker image alpine ( you can take any image)
docker pull alpine
2. tag the image with private IP address of Registry server
docker image tag alpine 192.168.33.10:5000/prvalpine
3. verify the tagged docker image got created
docker images
4. create Docker registry container (if you haven't create it)
docker container run -d -p 5000:5000 --name local_registry registry
5. push the tagged docker image (it will throw an error because the repository is not secure)
docker push 192.168.33.10:5000/prvalpine
Error:-> Get https://192.168.33.10:5000/v2/: http: server gave HTTP response to HTTPS client
Remedy: If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Remember to change your IP as per your docker host system IP)
{
"insecure-registries": ["192.168.33.10:5000"]
}
6. restart the Docker daemon
systemctl restart docker
7. start the Docker registry Container (cause once you restart, containers will be exited)
docker start local_registry
8. push the tagged image (this time it should be pushed to docker registry without any error)
docker push 192.168.33.10:5000/prvalpine
Pull the insecure private registry on a different remote system
Take another Virtual Machine that is in the same network and install docker into that remote machine
1. Install docker
apt update && apt install docker.io -y
2. If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Please change IP as per your docker host system IP)
{
"insecure-registries": ["192.168.33.10:5000"]
}
3. restart the Docker daemon
systemctl restart docker
4. pull the Docker Registry image from the private registry
docker pull 192.168.33.10:5000/prvalpine
5. verify image is available on this system
docker images
Take another Virtual Machine that is in the same network and install docker into that remote machine
1. Install docker
apt update && apt install docker.io -y
2. If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Please change IP as per your docker host system IP)
{
"insecure-registries": ["192.168.33.10:5000"]
}
3. restart the Docker daemon
systemctl restart docker
4. pull the Docker Registry image from the private registry
docker pull 192.168.33.10:5000/prvalpine
5. verify image is available on this system
docker images
C) Pulling a Docker Registry from a registry of another host machine (2nd method: securely)
1. remove daemon.json file on Docker Registry and Remote System
rm /etc/docker/daemon.json
2. restart docker service
systemctl restart docker
3. remove local_registry Container on Docker Registry Server ( if it is in running state)
docker rm -f local_registry
4. create a directory to keep the certificates on Docker Registry Server
mkdir /certs
5. create a directory certs in /etc/docker directory (when docker container run, it will first search any certification in this directory)
mkdir /etc/docker/certs.d
6. create a directory for images
mkdir /my_repo
7. create a self signed certificate with openssl utility. (this will create public key .crt and private key .key)
openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/domain.key -x509 -days 365 -out /certs/domain.crt
it asks some optional questions but the mandatory step is to provide common name
common Name :- repo.docker.kmit ( you can give any name)
it will ask email address too, just press enter
check:
ls /certs (domain.key and domain.crt will be created)
8. create a directory with repo.docker.kmit:5000 under /etc/docker/certs.d directory (-p is used if certs.d is not created (parent directory))
mkdir -p /etc/docker/certs.d/repo.docker.kmit:5000
9. go to /certs directory
cd /certs
10. copy /certs/domain.crt file to /etc/docker/certs.d/repo.docker.kmit:5000 with name ca.crt
cp domain.crt /etc/docker/certs.d/repo.docker.kmit:5000/ca.crt
11. run a secure registry on a container and config the container (-v is volume, whatever is in my_repo map it into /var/lib/registry -e is environment variable)
docker run -d -p 5000:5000 -v /my_repo:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key --restart on-failure --name myregistry registry
Remedy: provide repo.docker.kmit name by adding entry in /etc/hosts file (192.168.33.10 is docker host ip change it as necessary)
vi /etc/hosts
Create a directory /etc/docker/certs.d/repo.docker.kmit:5000
Copy valid certificate domain.crt file from docker Registry server and keep it at /etc/docker/certs.d/repo.docker.kmit:5000/ (hmm..how?)
Pull docker image from docker registry and it will be sucessfull
docker pull repo.docker.kmit:5000/mysql
8. create a directory with repo.docker.kmit:5000 under /etc/docker/certs.d directory (-p is used if certs.d is not created (parent directory))
mkdir -p /etc/docker/certs.d/repo.docker.kmit:5000
9. go to /certs directory
cd /certs
10. copy /certs/domain.crt file to /etc/docker/certs.d/repo.docker.kmit:5000 with name ca.crt
cp domain.crt /etc/docker/certs.d/repo.docker.kmit:5000/ca.crt
11. run a secure registry on a container and config the container (-v is volume, whatever is in my_repo map it into /var/lib/registry -e is environment variable)
docker run -d -p 5000:5000 -v /my_repo:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key --restart on-failure --name myregistry registry
Remedy: provide repo.docker.kmit name by adding entry in /etc/hosts file (192.168.33.10 is docker host ip change it as necessary)
vi /etc/hosts
192.168.33.10 repo.docker.kmit
12. download any image and tag it with the common name: repo.docker.kmit:5000
docker pull mysql
docker image tag mysql repo.docker.kmit:5000/mysql
13. push it to docker registry
docker push repo.docker.kmit:5000/mysql
12. download any image and tag it with the common name: repo.docker.kmit:5000
docker pull mysql
docker image tag mysql repo.docker.kmit:5000/mysql
13. push it to docker registry
docker push repo.docker.kmit:5000/mysql
Pulling Images securely on Client or Remote System
1. login to remote system which is on same network and docker is installed on it.
Resolve repo.docker.kmit name by adding entry in /etc/hosts file ( 192.168.33.10 is docker registry ip )
192.168.33.10 repo.docker.kmit
1. login to remote system which is on same network and docker is installed on it.
Resolve repo.docker.kmit name by adding entry in /etc/hosts file ( 192.168.33.10 is docker registry ip )
192.168.33.10 repo.docker.kmit
Create a directory /etc/docker/certs.d/repo.docker.kmit:5000
Copy valid certificate domain.crt file from docker Registry server and keep it at /etc/docker/certs.d/repo.docker.kmit:5000/ (hmm..how?)
ANSIBLE!
ansible 192.168.33.11 -m copy -a "src=/certs/domain.crt dest=/etc/docker/certs.d/repo.docker.kmit:5000/domain.crt"
Pull docker image from docker registry and it will be sucessfull
docker pull repo.docker.kmit:5000/mysql