2

I've set up a Docker Swarm consisting of two VMs on my local network, (1 manager, 1 worker). In the manager node, I created a private registry service and I want to deploy a number of locally built images in my local dev machine (which is not in the swarm) to that registry. The Swarm docs and the dozens of examples I've read in the Internet seem not to go beyond the basics, running commands inside the manager node, building, tagging and pushing images from the manager's local cache to the registry in that same node, and I have that uneasy feeling that I'm missing something right on my face.

I see that my machine could simply join the swarm as a manager, owning the registry. The other nodes would automagically receive the updates and my problem would go away. But does this make sense for a production swarm setting, a cluster of nodes serving production code, depending on my dev's home machine - even as non-worker, manager-only?

Things I've tried:

  • Retagging my local image to <my.node.manager.ip>/my_app:1.0.0, followed by docker-compose push. I can see this does push the image to the manager's registry, but the service fails to start with the message "No such image: <my.node.manager.ip>/my_app:1.0.0"
  • Creating a context and, from my machine, run docker-compose --context my_context up --no-start. This (re)creates the image in the manager node's local cache, which I can then push to the registry, but it feels very unwieldy as a deploy process.

Should I run a remote script in the manager node to git pull my code and then do the build/push/docker stack deploy?

TL;DR What's the expected steps to deploy an image/app to a Docker Swarm from a local dev machine outside the swarm? Is this possible? Is this supported by Docker Swarm?

Lavos Core
  • 21
  • 3
  • 1
    You don't need to join with your dev machine as manager to push to the local docker registry, joining as worker will work as long as you use the registry credentials. Now, if you wish to have a proper "devops" environment, your registry should actually be a third dedicated machine, with proper hostname and visibility (LAN or WAN) and outside the swarm. Your question is a tad too broad, though, and depends a lot on other details of your use case. – amiasato Mar 26 '21 at 02:31
  • But by joining as worker, won't my machine become a target for receiving tasks from the manager? Sure, I can prevent this with labels/constraints, but that added complexity just for deploying feels a bit odd to me. I'll look up on registries outside the swarm. Thanks! – Lavos Core Mar 26 '21 at 04:53

1 Answers1

0

After reading a bit more on private registries and tags, I could finally wrap my head around the necessary tagging for my use case to work. My first approach was halfway right, but I had to change my deploy script so as to:

  1. extract the image field from my docker-compose.yml (in the form localhost:5000/my_app:${MY_APP_VERSION-latest}, to circumvent the "No such image" error)
  2. create a second tag for pushing to the remote registry, replacing "localhost" by my manager node address (where the registry is at)
  3. Tag my locally built image with that tag and docker-compose push it
  4. Deploy the app with docker --context <staging|production> stack deploy my_app

I'm answering myself since I did solve my original problem, but would love to see other DevOps implementations for similar scenarios.

Lavos Core
  • 21
  • 3