Search code examples
dockerdocker-swarmdocker-stack

Stop, upgrade, start all Docker Stack services together?


I'd like to stop all services in my docker-stack.yml file, update the file with new image version numbers, and then start all services. In order to upgrade them all together, so that they're always all of them at the very latest version.

How do I do this? I'd rather not delete networks and volumes — I mean, docker stack rm seems like overkill? And docker service scale service-name=0 feels error prone? then one needs to remember to change back to > 0 again.

The reason I want to do a stop-everything upgrade, is that it's simpler: The services in my app then won't need to be compatible with different versions of each other's APIs. There'll never be version X of a service running and having to communicate with version X - 1 of another service (instead, all services will be on the same version X. They use the same version numbers).

(And feel free to let me know if I'm asking the wrong question :- ) Note: In this particular case, 20 - 30 seconds downtime because all containers stop-upgrade-restart at once, is okay. And this is for Docker Swarm / Stack, not Docker-Compose (then one could just do down and up). )


Solution

  • Disclaimer: I feel like this is the wrong approach to upgrades. It introduces downtime into a system that's designed to be highly available.


    To stop a service, I'd probably add a constraint that cannot be satisfied, e.g.

    docker service update \
      --constraint-add node.label.disable_service==true -d \
      ${service_name}
    

    This covers both replicated and globally scheduled services. When you redeploy a stack using a compose file, it will remove this constraint (it should also remove any scale changes).


    If your stack is as tightly coupled as you describe, something close to a blue/green deployment may be a better option. Put a proxy in front of your services attached to two docker networks, and start your blue or green stack on one of those networks. Then to replace it, start the other stack on the other network, and once running and the proxy is routing traffic, stop the first stack.