Containers & Orchestration·8 min read·

Rolling Updates and Zero-Downtime Deploys in Docker Swarm

Deploy updates to a Swarm service with zero downtime using order start-first, health checks, health thresholds, and automatic rollback.

NB

Netbay Engineering

Netbay Engineering

On this page

The reason teams adopt an orchestrator is usually not scale — it is the ability to update software without taking the service down and to fall back automatically when a deploy goes wrong. Docker Swarm gives you that with a small set of service options: rolling update order, health check thresholds, and a rollback action. If your app already has a health endpoint, Swarm can gate every release on it.

This post walks a zero-downtime deploy on a Swarm service and explains the flags that actually matter.

Anatomy of a Rolling Update

A rolling update replaces replicas in batches. Swarm compares the running image with the target, and depending on update_config, it starts new replicas before stopping old ones (start-first) or the reverse (stop-first). Start-first is what gives you zero downtime for HTTP services: new tasks come up, pass their health check, and then the old ones are taken down.

yaml
version: "3.8"
services:
  web:
    image: myapp:1.6.0
    ports:
      - target: 80
        published: 80
        mode: host
    deploy:
      replicas: 4
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
        failure_action: rollback
        max_failure_ratio: 0.5
        monitor: 30s
      restart_policy:
        condition: on-failure
      healthcheck:
        test: ["CMD", "curl", "-fs", "http://localhost/health"]
        interval: 10s
        timeout: 5s
        retries: 3
        start_period: 20s

The monitor window is how long Swarm watches a freshly started task before it calls it healthy; max_failure_ratio says how many failures are allowed before the whole update rolls back. Commit this as a Compose stack and you have locked-in deploy behaviour.

The Deploy Command

With the stack defined, updates are a single command. Swarm reconciles toward the new spec and reports status as it goes:

bash
docker stack deploy -c stack.yml myapp
docker service ps myapp_web
docker service update --image myapp:1.6.0 myapp_web
docker service inspect --pretty myapp_web

A deliberate update with a new tag works the same way. Watch docker service ps and you will see the rolling progress: running tasks stay 4 while new ones come and go.

What "Zero Downtime" Actually Requires

The orchestrator only does its half. Your app contributes the rest:

  1. A health endpoint that reflects real readiness, not just "process is up".
  2. No schema migration so destructive that old and new instances cannot both run at once.
  3. Graceful shutdown — handle SIGTERM and finish in-flight requests.
  4. The load balancer (Swarm's ingress or a proxy) evenly distributes only to healthy tasks.
t0: old image new A health 1 old rest new B old 1 left all new tasks

Updates Gone Wrong: Rollback

Even with care, a bad release happens. Because failure_action: rollback is in the spec, Swarm automatically reverts to the last known-good image the moment failures exceed the ratio, so you wake up to a service that recovered on its own instead of a page.

bash
docker service update --image myapp:1.5.0 myapp_web
docker service ps myapp_web  # rollback_history shows the path back

Keep two or three old tags in the registry so rollback is embarrassingly easy after the fact.

Takeaway

Swarm's rolling update and rollback controls turn a VPS host into a job that deploys itself safely, as long as your app reports honest health. Run a small Swarm on a couple of Netbay instances, define this stack, and ship tags with confidence — provision your nodes at netbayhosts.in in under a minute each.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance