1. Introduction
Private Docker repositories are often used in cloud applications and for many reasons. Images may have content we cannot share, or maybe they aren’t useful to others.
In this tutorial, we’ll discuss how docker-compose can access private repositories using the docker login command.
2. Using docker login
We often pull and run public images when using Docker, without the need to log in. We only need to log in when we have to access private repositories.
Let’s see how to use the docker login command to do that interactively:
$ docker login
...
Username: myuser
Password:
Login Succeeded
$
$ docker pull myuser/hello-world
Using default tag: latest
latest: Pulling from myuser/hello-world
Digest: sha256:...
Status: Downloaded newer image for myuser/hello-world:latest
docker.io/myuser/hello-world:latest
We can later do docker login without supplying our credentials again. This is because they are already stored on our machine.
We could use any Docker registry to save our images, not only the default one. We may choose among many Docker registries that are offered as a service, often for free.
To log in to a different registry we only need to add it after the docker login command:
$ docker login some-other-docker-registry.io
After logging in our credentials for this new registry are stored in our machine. We’re then logged in to both registries at the same time.
Later, when we want to access the image we need to mention the repo explicitly:
$ docker pull some-other-docker-registry.io/hello-world
3. How login Helps docker-compose
docker-compose is a convenient tool to spin up a multi-container docker application. It allows us to define in a single file all images, even if they are stored in different registries.
Let’s say we need to work with different registries and levels of access. In this case, our docker-compose.yml file might begin:
version: '3'
services:
public:
image: hello-world
private:
image: myuser/hello-world
other-registry:
image: some-other-docker-registry.io/myuser/hello-world
We used the hello-world image to simplify our example. It’s an official image that only prints how to get started with Docker and finishes right after.
The first two services reference images in the default Docker registry. The first is a public image, and the second is private. The third image is stored in a private repository on a different registry.
We should be logged in to both registries before using docker-compose for the first time. That way our credentials will be stored in our machine:
$ docker login
Login with your Docker ID ...
Username: myuser
Password:
Login Succeeded
$
$ docker login some-other-docker-registry.io
Username: myuser
Password:
Login Succeeded
Only then can we start all services with docker-compose:
$ docker-compose up
Creating network "login_default" with the default driver
...
public_1 | Hello from Docker!
public_1 | ...
other-registry_1 | Hello from Docker!
other-registry_1 | ...
login_public_1 exited with code 0
private_1 | Hello from Docker!
private_1 | ...
login_private_1 exited with code 0
login_other-registry_1 exited with code 0
$
$ docker-compose down
...
That’s it! We made docker-compose access private repositories in different registries.
Let’s now compare the successful output above with the error we get when we’re not logged in. First, we had to log out and delete the image downloaded locally in order to see the error:
$ docker logout
Removing login credentials for https://index.docker.io/v1/
$ docker image rm myuser/hello-world
...
$
$ docker-compose up
Creating network "login_default" with the default driver
Pulling private (myuser/hello-world:latest)...
ERROR: pull access denied for myuser/hello-world, repository does not exist or may require 'docker login':
denied: requested access to the resource is denied
4. Conclusion
In this short article, we learned that private repositories can be accessed only after logging in.
We also learned that docker-compose requires docker login once per registry. After that, docker-compose will always work.