One of the things that makes the Docker Platform so powerful is how easy it is to use images from a central location. Docker Hub is the premier Image Repository with thousands of Official Images ready for use. It’s also just as easy to push your own images to the Docker Hub registry so that everyone can benefit from your Dockerized applications.
But in certain scenarios, you might not want to push your images outside of your firewall. In this case you can set up a local registry using the open source software project Distribution. In this article we’ll take a look at setting up and configuring a local instance of the Distribution project where your teams can share images with docker commands they already know: docker push
and docker pull
.
Prerequisites
To complete this tutorial, you will need the following:
- Free Docker Account
- You can sign-up for a free Docker account and receive free unlimited public repositories
- Docker running locally
Running the Distribution service
The Distribution project has been packaged as an Official Image on Docker Hub. To run a version locally, execute the following command:
$ docker run -d -p 5000:5000 --name registry registry:2.7
The -d
flag will run the container in detached mode. The -p
flag publishes port 5000 on your local machine’s network. We also give our container a name using the --name
flag. Check out our documentation to learn more about these and all the flags for the docker run
command.
Pushing and Pulling from a local registry
Now that we have our registry running locally, let’s tail the container’s logs so we can verify that our image is being pushed and pulled locally:
$ docker logs -f registry
Open another terminal and grab the Official Ubuntu Image from Docker Hub. We’ll use this image in our example below:
$ docker pull ubuntu
To push to or pull from our local registry, we need to add the registry’s location to the repository name. The format is as follows: my.registry.address:port/repositoryname
.
In our example, we need to replace my.registry.address.port
with localhost:5000
because our registry is running on our localhost and is listening on port 5000. Here is the full repository name: localhost:5000/ubuntu
. To do this, we’ll run the docker tag
command:
$ docker tag ubuntu localhost:5000/ubuntu
Now we can push to our local registry.
$ docker push localhost:5000/ubuntu
NOTE:
Docker looks for either a “.” (domain separator) or “:” (port separator) to learn that the first part of the repository name is a location and not a user name. If you just had localhost without either .localdomain or :5000 (either one would do) then Docker would believe that localhost is a username, as in localhost/ubuntu or samalba/hipache. It would then try to push to the default Registry which is Docker Hub. Having a dot or colon in the first part tells Docker that this name contains a hostname and that it should push to your specified location instead.
Switch back to the terminal where our registry logs are being tailed. If you review the logs, you will see entries displaying the request to save our ubuntu image:
...
172.17.0.1 - - [26/Feb/2021:18:10:57 +0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 202 0 "" "docker/20.10.2 go/go1.13.15 git-commit/8891c58 kernel/4.19.121-linuxkit os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.2 \\(darwin\\))"
172.17.0.1 - - [26/Feb/2021:18:10:57 +0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 202 0 "" "docker/20.10.2 go/go1.13.15 git-commit/8891c58 kernel/4.19.121-linuxkit os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.2 \\(darwin\\))"
172.17.0.1 - - [26/Feb/2021:18:10:57 +0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 202 0 "" "docker/20.10.2 go/go1.13.15 git-commit/8891c58 kernel/4.19.121-linuxkit os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.2 \\(darwin\\))"
...
Now let’s remove our localhost:5000/ubuntu
image and then pull the image from our local repository to make sure everything is working properly.
First print a list of images we have locally:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.7 5c4008a25e05 40 hours ago 26.2MB
ubuntu latest f63181f19b2f 5 weeks ago 72.9MB
localhost:5000/ubuntu latest f63181f19b2f 5 weeks ago 72.9MB
Now remove the localhost:5000/ubuntu:latest
image from our local machine:
$ docker rmi localhost:5000/ubuntu
Untagged: localhost:5000/ubuntu:latest
Untagged: localhost:5000/ubuntu@sha256:3093096ee188f8...8c091c8cb4579c39cc4e
Let’s double check the image has been removed:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.7 5c4008a25e05 40 hours ago 26.2MB
ubuntu latest f63181f19b2f 5 weeks ago 72.9MB
Finally pull the image from our local registry and verify that it is now pulled to our local instance of Docker.
$ docker pull localhost:5000/ubuntu
Using default tag: latest
latest: Pulling from ubuntu
Digest: sha256:sha256:3093096ee188f8...8c091c8cb4579c39cc4e
Status: Downloaded newer image for localhost:5000/ubuntu:latest
localhost:5000/ubuntu:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.7 5c4008a25e05 40 hours ago 26.2MB
ubuntu latest f63181f19b2f 5 weeks ago 72.9MB
localhost:5000/ubuntu latest f63181f19b2f 5 weeks ago 72.9MB
Summary
In this article, we took a look at running an image registry locally. We also pulled an image for Docker Hub, tagged the image with our local registry and then pushed that image to our local registry running Distribution.
If you would like to learn more about the Distribution project, head on over to the open source project homepage on GitHub and be sure to check out the documentation.