Recently I was looking for a way to push services’ images of a Docker Compose project to a private registry. In this article I’m going to save you some guesswork as the process is a bit ambiguous.
Before we go any further let’s first set up the stage. We have a simple docker-compose.yml file with the following contents:
version: '3'
services:
myapp:
build: ./services/myapp
I want to build the image and push it to my private Docker registry.
docker-compose build
So far so good. Everything builds well. I decide to check my local images:
docker images
And the first issue I notice is the bad naming of my image:
“myprojectname_myapp latest”
Easy fix — if you specify image as well as build configuration options, docker-compose will build the image with the specified image name and tag, as described in the docs:
version: '3'
services:
myapp:
image: myproject/myapp:latest
build: ./services/myapp
Now my image has appropriate naming and I want to push it. With the current setup, however, docker-compose push
will try to push the project’s images to the Docker Hub registry. I don’t want this to happen.
At first glance the compose file reference doesn’t provide neither configuration nor information on how to push images to a private registry.
If you want to push an image to a private registry you need to follow those instructions:\
1.
docker tag myproject/myapp:latest my-registry-host:5000/myproject/myapp:latest
\2.
docker push my-registry-host:5000/myproject/myapp:latest
There are some guides on the Internet suggesting automating those steps with a script but I don’t like this solution as I want to use the native tooling. A few minutes later I arrived at the docker-compose push documentation page which includes a nice example.
It looks like the image service configuration option follows the same notation as the example above:
version: '3'
services:
myapp:
image: my-registry-host:5000/myproject/myapp:latest
build: ./services/myapp
Now when I execute docker-compose push
my image gets pushed to my private image registry. There is something that still annoys me though — if I decide to change the registry, I need to edit the image configuration option of all described services.
For this reason I like to extract the registry host as an environment variable:
REGISTRY_HOST=my-registry-host:5000
version: '3'
services:
myapp:
image: ${REGISTRY_HOST}/myproject/myapp:latest
build: ./services/myapp
Congratulations! Now you will be able to build and distribute your project’s images by only using the native tooling provided by Docker and Docker Compose.