Today I was trying to generate a Docker image from a Node.js project and I wanted to deploy it on my local test swarm.
Unfortunately if one builds a local Docker image, this image is stored and accessible only to the node it was created on and the other swarm nodes can’t access it.
The way to fix this is to push the image to a Docker registry where it can be pulled from by all the nodes in the swarm.
Creating the registry
To instantiate a registry service in the swarm, run:
docker service create --name registry --publish 5000:5000 registry:latest
This will create the registry service and run it in the swarm, making it accessible to all the nodes in the swarm.
Pushing an image to the registry
To push an image to the registry, you have to do two things – tag and then push the image.
Here’s an example on how to build and tag the image in one go:
docker build . -t localhost.localdomain:5000/<image-name>:latest
And how to push it to the registry:
docker push localhost.localdomain:5000/<image-name>:latest
Using the image in a service/container/etc
To use the image in a service or a container, you specify the full path from above, i.e. localhost.localdomain:5000/<image-name>:latest.
Swarm nodes will have access to the image and will be able to pull and run it.
Important note about the registry address
In most tutorials online, the registry URL is given as localhost:5000. Unfortunately this doesn’t work and usually it times out when trying to use it. If we change this to localhost.localdomain it will work!
Not sure why this happens when both localhost and localhost.localdomain resolve to 127.0.0.1.