Iv) Grant the Anonymous user access to the docker repositories. By default, the Anonymous user is granted the nx-anonymous role which includes privileges to browse, read and search all repositories. To grant additional access to the docker repositories, you can create a new role with additional privileges and assign the role to the Anonymous user. First, create a directory on your computer where you want to save all the Docker images of your private Docker image repository. $ mkdir -p / docker / repository. Now, create a container of the registry image from the Docker Hub with the following command: $ docker container run -d -p 5000: 5000 -name registry -v.
A private Docker registry allows you to share your custom base images within your organization,keeping a consistent, private, and centralized source of truth for the building blocks of your architecture.A private Docker registry gives you better performances for big clusters and high-frequency roll-outs,plus added features like access authentication.
In an earlier post, we had a look at how one could store Docker images in Exoscale’s S3-compatible object storage.
We described how to configure a Docker registry storing images on Exoscale’s Object Storage, yet this keeps the local Docker instance responsible for the processing itself.
To improve availability, a registry would be better hosted on an external server.
Let’s see how to setup a private registry, and then later how to secure the whole thing.We will split the process in two, setting up first and securing the registry later.
What is a private Docker registry anyway?
After building a Docker image on your machine, it’s possible to run it on the spot.But if you’re a software provider, what if you want to share the image with the whole world?Or, what if you want to privately share the image with your team?
A registry can be considered private if pulling requires authentication
A Docker registry is a place where you can store your images i.e.docker push
, and let third-parties get them i.e.docker pull
.Docker Hub is the default registry.For example, let’s run:
In a very simplified way, the process goes like this:
- Check if the
hello-world
image is found locally - If it isn’t, pull it from Docker Hub
- Register it in the local Docker.The image is now available locally
- Run it via the local Docker daemon
Note that while you can pull freely, pushing still requires some kind of authentication.
A registry can be considered private if pulling requires authentication too.
For example, GitLab, a popular Continuous Integration platform,provides a Docker registry per project among more traditional “build” capabilities,and it can be configured to be freely accessible or private.
However, GitLab’s registry is a solution that is still a bit rough around the edges.
It’s quite hard to remove images (while it’s possible to untag them though), andmore importantly, using the SaaS version of Gitlab’s registry is an all-or-nothing option:there’s no way to customize it e.g. integrate it with one’s identity store for authenticated access.
Let’s start from scratch instead, and publish our private registry on Exoscale’s cloud servers.
How to set up a private Docker registry
Good news, a Docker registry is just a Docker image!So, in order to set up a Docker registry, you first need to…setup Docker itself.
How to securely install the latest Docker release
There are two ways to install Docker:
- From a package:this requires downloading a specific package and manually installing it e.g.
dpkg my-package.deb
- From a repository e.g.
apt-get install my-package
.
Installing from a repository makes updates to installed packages applied in an automated way.
The biggest advantage of this approach is that the system will always benefit from the latest security patch.In the light of some recent security scandals related to an outdated library/package, it seems there’s no other way.
Let’s choose option 2 using a fresh Ubuntu instance. To install Docker is just as easy as:
However, getting the latest and greatest version requires a bit more effort,as the official Ubuntu repository lags behind the Docker release cycle.
To do so, the official Docker package repository should first be added to the list of available repositories.This requires some preliminary setup, as it is a security-sensitive operation.
As key system components, packages should be signed and verified.The provider will sign a package using a private key, and provide a public key so that a third-party can check it’s genuine.Since the check process is handled by the system, we need to provide it with the Docker GPG public key first.
If somebody hacked the previous site to set its own key, it could impersonate the Docker organization and sign malicious packages.We need to assert this is the correct key:
0EBFCD88
is part of Docker’s public key.This should output something akin to the following:Notice that the
uid
contains the string0EBF CD88
that we searched for, as well asDocker Release (CE deb) <[email protected]>
.At this point, we have allowed the installation of packages signed by Docker.Add the proper repository:
Install Docker (finally):
To test the correct installation, execute this command:
This should yield the following:
Great, let’s pat ourselves on the back because at this point, Docker is (finally) ready to use.Remember that we had to process all those steps because the out-of-the-box Ubuntu repository doesn’t contain the latest version of Docker.
How to install the Docker registry on a virtual machine
Now is time for the proper Docker registry installation.Interestingly enough, this might be the easiest part of the whole setup process.As stated above, a Docker registry is just a specific running container, registry.

That command:
- downloads the registry image which is tagged
2
.This tag references the latest version of the registry at the time of this writing. - exposes port 5000 to the host, under the same port
- gives the container the name
registry
instead of assigning it a random name
To make sure that the registry is running, a simple docker ps
should display the following (abridged for readability):
How to push a custom Docker image to a remote private registry
Now, to test that the registry behaves as attended, let’s push a basic image to our brand-new shiny registry.We will use the hello-world
image.
The goal is now to push the local image to the registry available remotely.
Docker Registry
If you followed the above procedure, you might have noticed the hello-world
image is already available on the remote Docker.Now, you might think if you push, nothing will change because the image is already present remotely, but this is actually wrong.
There’s a clear difference between an image available to Docker, and an image stored in a Docker registry.
- In the first case, it can be listed and run by the Docker daemon to which it belongs.
- In the second case, it cannot.
For an image stored in a registry to be run requires it to be first pulled to a Docker instance.
There’s one constraint though, the image’s name needs to be prefixed with the registry’s URL (whether domain-based or IP), port included e.g.159.100.243.157:5000/hello-world
.
This is the responsibility of the docker tag
command:
The new label should now appear:
Although listed with two different labels, the very same hello-world
image is referenced, so that the disk space is used only once.You can make sure of that by looking at the image ID (4ab4c602aa5e
in our case).
Labels are in fact pretty similar to links created by the ln
command.If you remove one of the labels, the image will still be available with the other one.In order to remove the image altogether, it has to be referenced without a label.
Now is time to push the image to the registry, with the docker push
command:
Chances are high to get the following error output:
Docker expects a secured channel by default, and that’s naturally a very good thing.But TLS adds another layer of complexity, and possible issues, so let’s skip that for now and we’ll come back on the subject a bit later.
Configuring Docker to accept connections to unsecure registries depends on your OS,but it’s quite straightforward. In all cases you will need to update a daemon.json
file.
On Linux the .json file is located /etc/docker/daemon.json
and assuming no other setting is present in the file, it should look like this:
You can create the file if does not exist, and you will need to restart Docker afterwards for the changes to take effect.On macOS you do it using the user interface, and the changes will automatically restart the daemon:
- Click on the Docker icon
- Select Preferences… in the menu
- Select the Daemon tab
- Check the checkbox named Experimental features
- In the first list box, enter the address (URL or IP) of the unsecure registry e.g. 159.100.243.157:5000
Wait a bit for the Docker daemon to restart, then push again to the registry with the same command-line as above.This time, it should be a success:
The image should now be safely stored on the Docker registry we set up.In order to make sure of that, we can ask this remote registry what images it contains.Fortunately, the registry also offers a web API to query stored images.
From any machine, type:
This should return:
Security considerations
Congratulations, you managed to install your own private Docker registry and push your image to it!Remember that at this point, the registry is not secured, and in more than one way.
We have seen while pushing to the registry that Docker expects a secured channel by default, but we have skipped it to keep things simple.Moreover, anybody can push to, or pull from the registry…
You should never leave it in such a state for a real-world setup!If you do, bad things will happen sooner or later, as Aeroflot can attest.
We will show you how to secure your registry in another blog post, follow us on Twitter to stay tuned!
References
- 1Installation
- 4'WARNING: No {swap,memory} limit support'
Installation
The Docker package is in the 'Community' repository. See Alpine_Linux_package_management how to add a repository.
Connecting to the Docker daemon through its socket requires you to add yourself to the `docker` group.
To start the Docker daemon at boot, see Alpine_Linux_Init_System.
For more information, have a look at the corresponding Github issue.
This weakening of security is not necessary to do with Alpine 3.4.x and Docker 1.12 as of August 2016.
Docker Compose
'docker-compose' is in the 'Community' repository starting with Alpine Linux 3.10.
For older releases:
To install docker-compose, first install pip:
Isolate containers with a user namespace
add to /etc/docker/daemon.json
You may also consider these options : '
You'll find all possible configurations here[1].
Example: How to install docker from Arch
'WARNING: No {swap,memory} limit support'
You might encounter this message when executing docker info
.To correct this situation, we have to enable the cgroup_enable=memory swapaccount=1

Alpine 3.8
It may not have been the case before, but with Alpine 3.8, you must config cgroups properly

Warning: This seems not to work with Alpine 3.9 and Docker 18.06. Follow the instructions for grub or extlinux below instead.
Grub
If you use Grub, add the cgroup condition into /etc/default/grub
, then upgrade your grub
Add Docker Repository
Extlinux
With Extlinux, you add the cgroup condition, but inside of /etc/update-extlinux.conf
then update the config and reboot
update-extlinux
How to use docker
The best documentation on using Docker and creating containers is at the main docker site. Adding anything to it here would be redundant.
If you create an account at docker.com, you can browse through user images and learn from the syntax in contributed dockerfiles.
Official Docker image files are denoted on the website by a blue ribbon.