Docker Registry/Repository (Insecure)
Whenever we use docker image pull command to pull an official docker image, that image is downloaded from a docker registry hosted on a remote server on a remote location.
But what if we want to download or push these images from our own private registry instead of the docker registry or Docker Hub.
This can be achieved using Docker Registry.
The Registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images. The Registry is open-source, under the permissive Apache license.
How to install the docker registry?
Docker provides its own image named registry for this purpose. We need to pull this image and run a container using this image.
gaurav@learning-ocean:~$ docker container run -d -p 5000:5000 --name simple_registry registry
e3835d2ab35d7883f84db1c65cf6e7ef5b4e1a85cdd1e63bc452ee379f56fdee
In the above command, we are running the container using the registry image, we have provided a name for the container and a port. By default it listens on port 5000 and also we have not assigned any volume in this command, a volume will be created automatically by default.
gaurav@learning-ocean:~$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3835d2ab35d registry "/entrypoint.sh /etc…" 11 seconds ago Up 10 seconds 0.0.0.0:5000->5000/tcp simple_registry
gaurav@learning-ocean:~$
Our container is running now. Now we want to check how many images are present in our registry at this point. For this just curl to this URL
gaurav@learning-ocean:~$ curl http://127.0.0.1:5000/v2/_catalog
{"repositories":[]}
gaurav@learning-ocean:~$
As you can see,there is no image present currently.
Now we will add an image to this registry.
First let us inspect our container and check the volume attached to our container.
gaurav@learning-ocean:~$ docker container inspect e38
# few lines removed from output
"Mounts": [
{
"Type": "volume",
"Name": "e37eda0e6eab78298f050ea5b6abffec94cb49c59c87f6edb8d7aaad470fae70",
"Source": "/var/lib/docker/volumes/e37eda0e6eab78298f050ea5b6abffec94cb49c59c87f6edb8d7aaad470fae70/_data",
"Destination": "/var/lib/registry",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
# few lines removed from output
We can see the output of the inspect command and find the volume information in the format shown in the above output.
In case if our container stops by any chance and we want to run the container again then we can attach the same volume to the container using the above volume information.
Also notice that the driver in the above volume information is ‘local’ because our data will be stored on the local file system, there are also drivers available for remote cloud storage as well which we can use to store our data remotely such as AWS S3, Google Cloud, Azure etc.
Now coming back to pushing an image to the local registry.
gaurav@learning-ocean:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1318b700e415 7 days ago 72.8MB
redis latest aa4d65e670d6 11 days ago 105MB
nginx latest 08b152afcfae 12 days ago 133MB
mysql latest c60d96bd2b77 12 days ago 514MB
registry latest 1fd8e1b0bb7e 3 months ago 26.2MB
ubuntu 14.04 13b66b487594 4 months ago 197MB
gaurav@learning-ocean:~$
We will be pushing the redis image to the local registry.
Now we run the following command so that the image points to our local registry instead of the default docker hub registry.
gaurav@learning-ocean:~$ docker image tag redis 127.0.0.1:5000/redis
gaurav@learning-ocean:~$
As seen in the below image our image with the local registry tag is created.
gaurav@learning-ocean:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1318b700e415 7 days ago 72.8MB
127.0.0.1:5000/redis latest aa4d65e670d6 11 days ago 105MB
redis latest aa4d65e670d6 11 days ago 105MB
nginx latest 08b152afcfae 12 days ago 133MB
mysql latest c60d96bd2b77 12 days ago 514MB
registry latest 1fd8e1b0bb7e 3 months ago 26.2MB
ubuntu 14.04 13b66b487594 4 months ago 197MB
gaurav@learning-ocean:~$
Now we will push this image to our local registry.
gaurav@learning-ocean:~$ docker image push 127.0.0.1:5000/redis
Using default tag: latest
The push refers to repository [127.0.0.1:5000/redis]
262de04acb7e: Pushed
45f6df634253: Pushed
e46136075591: Pushed
11f991845040: Pushed
dd1ebb1f5319: Pushed
814bff734324: Pushed
latest: digest: sha256:1bd57e1a42b99ae53412b582784d0362fa8205243ce5f289cb4f76de2907cb97 size: 1574
gaurav@learning-ocean:~$
The image is pushed. Now let’s verify if the image is pushed successfully or not. For verifying, curl to http://127.0.0.1:5000/v2/_catalog, we see that our image has been pushed successfully.
gaurav@learning-ocean:~$ curl http://127.0.0.1:5000/v2/_catalog
{"repositories":["redis"]}
gaurav@learning-ocean:~$
Now let us delete the Redis image present on our local file system.
gaurav@learning-ocean:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1318b700e415 7 days ago 72.8MB
127.0.0.1:5000/redis latest aa4d65e670d6 11 days ago 105MB
redis latest aa4d65e670d6 11 days ago 105MB
nginx latest 08b152afcfae 12 days ago 133MB
mysql latest c60d96bd2b77 12 days ago 514MB
registry latest 1fd8e1b0bb7e 3 months ago 26.2MB
ubuntu 14.04 13b66b487594 4 months ago 197MB
gaurav@learning-ocean:~$ docker image rm 127.0.0.1:5000/redis:latest redis:latest
Untagged: 127.0.0.1:5000/redis:latest
Untagged: 127.0.0.1:5000/redis@sha256:1bd57e1a42b99ae53412b582784d0362fa8205243ce5f289cb4f76de2907cb97
Untagged: redis:latest
Untagged: redis@sha256:cd0c68c5479f2db4b9e2c5fbfdb7a8acb77625322dd5b474578515422d3ddb59
Deleted: sha256:aa4d65e670d6518e5da96ca9d1a76370a942970a8802e6d5cc6bcf058ab12ca7
Deleted: sha256:3bd00d38f5ca70200050477c527cc60cfdf82911d6fe03932e2bcae31a95cfa2
Deleted: sha256:22722fde392d188cfbe5bbd0c2451cc71cf5b000afc0e5114c1066bb5e113ec9
Deleted: sha256:38212b55ef525e86cd726cd83c1a82a6009c68d24771d6e93d439fdc88e66f0e
Deleted: sha256:188c498579cef37b65a93d6448c6b129fa07d5740fc213a18843ff22d80cd10d
Deleted: sha256:2117165cd53c98f13ec7af36c9d8acd239fc541c847efaccb49885decf615d68
gaurav@learning-ocean:~$
If we disconnect our internet and try to pull the same image again, we get the below error as the default registry is unreachable.
But we are able to download the image from the local registry.
gaurav@learning-ocean:~$ docker image pull 127.0.0.1:5000/redis:latest
latest: Pulling from redis
33847f680f63: Already exists
26a746039521: Pull complete
18d87da94363: Pull complete
5e118a708802: Pull complete
ecf0dbe7c357: Pull complete
46f280ba52da: Pull complete
Digest: sha256:1bd57e1a42b99ae53412b582784d0362fa8205243ce5f289cb4f76de2907cb97
Status: Downloaded newer image for 127.0.0.1:5000/redis:latest
127.0.0.1:5000/redis:latest
gaurav@learning-ocean:~$
A point to note here is that docker only allows secure registry which are secured using TLS with the exception of localhost.
To check this let us tag another image to the IP allotted to our local machine.
gaurav@learning-ocean:~$ docker image tag redis 192.168.1.11:5000/redis
When we try to push this image,we get the error message shown in the below image which tells us to use https instead of http.
gaurav@learning-ocean:~$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1318b700e415 7 days ago 72.8MB
127.0.0.1:5000/redis latest aa4d65e670d6 11 days ago 105MB
redis latest aa4d65e670d6 11 days ago 105MB
nginx latest 08b152afcfae 12 days ago 133MB
mysql latest c60d96bd2b77 12 days ago 514MB
registry latest 1fd8e1b0bb7e 3 months ago 26.2MB
ubuntu 14.04 13b66b487594 4 months ago 197MB
gaurav@learning-ocean:~$ docker image push 192.168.1.11:5000/redis
Using default tag: latest
The push refers to repository [192.168.1.11:5000/redis]
Get https://192.168.1.11:5000/v2/: http: server gave HTTP response to HTTPS client
gaurav@learning-ocean:~$
To allow get the docker to allow insecure location, we need to modify docker configuration as follows:
We need to create the daemon.json file locally and add the IP which we want to allow to the IP list.
We have created the file daemon.json as follows in /etc/docker directory:
gaurav@learning-ocean:~$ cat /etc/docker/daemon.json
{
"insecure-registries": ["192.168.1.11:5000"]
}
Now we need to restart the docker service and our container which has stopped.
gaurav@learning-ocean:~$ sudo service docker restart
gaurav@learning-ocean:~$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3835d2ab35d registry "/entrypoint.sh /etc…" 32 minutes ago Exited (2) About a minute ago simple_registry
gaurav@learning-ocean:~$ docker container start e38
e38
gaurav@learning-ocean:~$
Now if we push our image again -
gaurav@learning-ocean:~$ docker image push 192.168.1.11:5000/redis
Using default tag: latest
The push refers to repository [192.168.1.11:5000/redis]
262de04acb7e: Layer already exists
45f6df634253: Layer already exists
e46136075591: Layer already exists
11f991845040: Layer already exists
dd1ebb1f5319: Layer already exists
814bff734324: Layer already exists
latest: digest: sha256:1bd57e1a42b99ae53412b582784d0362fa8205243ce5f289cb4f76de2907cb97 size: 1574
gaurav@learning-ocean:~$
The image is pushed successfully!
We can even pull this image from this insecure registry.