Rolling Updates in Docker Swarm Without Downtime
AI generated
FROM
RUN
Docker · Swarm · Deployment · DevOps
Rolling updates in Docker Swarm
Rolling out new versions without taking your shop offline

A rolling update replaces containers step by step with new versions, while the service stays continuously reachable for users. Without correctly configured health checks, parallelism and rollback rules, though, a single faulty deployment can still lead to a noticeable outage that a well designed rolling update prevents from the start.

17 min read Rolling Updates · Health Check · Rollback · Zero Downtime Docker 25+ · Swarm mode

1. What a rolling update in Swarm mode actually does

A rolling update replaces a service's containers step by step with a new version, instead of stopping and restarting all instances at once. Docker Swarm controls this process through the update strategy defined on the service: a configurable batch of containers gets stopped, replaced by new instances with the updated image, and only after a wait period does the next batch get touched. During this process, the remaining, not yet updated containers stay reachable and keep serving requests.

The decisive advantage of a rolling update over a full restart of all containers is continuous service availability throughout the entire deployment. For an online shop with multiple replicas, this means: while two of four containers are currently being updated, the other two keep serving customer requests. Only once all batches have run through successfully does the rolling update count as complete, and the application runs entirely on the new version.

2. The update_config section in detail

Controlling a rolling update happens through the update_config section in the deploy block of the compose file. The parallelism parameter sets how many containers get updated at once in a batch. A value of 1 updates containers one at a time and is the safest, but also the slowest. A higher value speeds up the update, but increases the risk that a faulty image affects multiple instances at the same time before the error is noticed.

The delay parameter defines the wait time between two batches and gives new containers time to fully boot and pass their health checks before the next batch starts. Too short a delay can cause several batches to run in parallel even though the previous one is not yet stable. For applications with a slow start, such as PHP applications with OPcache warmup, delay should be chosen generously enough to give the new container sufficient time.


# docker-compose.prod.yml — rolling update configuration
version: "3.9"

services:
  api:
    image: registry.example.com/shop-api:1.5.0
    networks:
      - backend
    deploy:
      replicas: 6
      update_config:
        parallelism: 2        # update 2 containers at a time
        delay: 15s             # wait 15s between batches
        order: start-first     # start new container before stopping old one
        failure_action: rollback
        monitor: 30s            # observe new container for 30s before continuing
        max_failure_ratio: 0.2  # tolerate up to 20% failed tasks per batch
      rollback_config:
        parallelism: 2
        delay: 10s
        order: stop-first

networks:
  backend:
    driver: overlay

3. Health checks as a prerequisite for safe updates

Without a configured health check, Docker Swarm cannot reliably determine whether a newly started container is actually functional. A container that runs but crashes internally because a database connection fails still counts as successful without a health check, as long as the main process keeps running. For a reliable rolling update, a health check is therefore not optional, it is the basic prerequisite so Docker can judge the actual application state instead of just the process status.

A good health check does not just check whether a process is running, but whether the application can actually answer requests correctly, for example via a dedicated /health endpoint that checks the database connection and critical dependencies. The start_period parameter gives the container time for its initial start before failed health checks count as critical, which matters especially for applications with a longer boot time, to avoid false alarms during normal startup.


# Health check configuration inside the Dockerfile or compose file
services:
  api:
    image: registry.example.com/shop-api:1.5.0
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s   # grace period during application boot

4. Automatic rollback on failed updates

The failure_action: rollback parameter in update_config enables an automatic rollback as soon as the share of failed tasks during a rolling update exceeds the threshold defined in max_failure_ratio. In this case, Docker Swarm immediately stops the running update and restores the previous, working version, without a human having to intervene manually. This automation is especially valuable outside office hours, when a CI pipeline deployment fails and nobody can react immediately.

The monitor parameter defines how long a newly started container is observed after the update before it counts as finally stable. If a container crashes within this observation window, Docker Swarm counts the batch as failed and holds it against max_failure_ratio. This combination of monitoring window and failure ratio gives teams control over how tolerant or strict the rolling update reacts to individual problems, without immediately aborting the entire deployment on every small outlier.


# Trigger a rolling update by changing the image tag
docker service update --image registry.example.com/shop-api:1.5.0 shop_api

# Manually trigger a rollback to the previous version if needed
docker service rollback shop_api

# Check whether the last update completed or rolled back
docker service inspect shop_api --format '{{.UpdateStatus.State}}'

5. Update order: start first versus stop first

The order parameter determines whether a new container gets started before stopping the old one (start-first) or whether the old container gets stopped first, before the new one starts (stop-first, the default value). start-first maximizes availability during the rolling update, because briefly more containers run than the configured replica count, but requires the application to cope with two versions running in parallel, for example with a database schema that is not yet fully migrated.

For most stateless web applications, start-first is the better choice, because it avoids downtime from capacity shortages during the update. stop-first, on the other hand, fits services with limited resources where there is not enough capacity for old and new versions running in parallel, for example services with exclusive access to a single external port without routing mesh support.

6. Rolling updates with database migrations

A rolling update becomes considerably more complex when a deployment includes a database schema change. During the update, both the old and the new application version briefly run in parallel, but both access the same database. A migration that renames or removes a column breaks the old application version as long as it is still active. The proven approach splits schema changes into several backward compatible steps, instead of coupling a single, breaking migration with the application code.

In practice this means: a new column is first added and optionally backfilled, in a second deployment the application code uses the new column, and only in a third, later deployment is the old column removed, after making sure no old application version accesses it anymore. This pattern, often called the expand contract pattern, makes rolling updates safe even for database changes, but requires discipline in splitting migrations into compatible intermediate steps.

7. Observing and verifying a rollout live

While a rolling update runs, docker service ps provides a live overview of all tasks, including newly started and terminated old instances. The CURRENT STATE column shows the progress of each individual task, from Starting through Running to Shutdown for the replaced old containers. This overview is the most reliable way to track in real time whether the update is progressing as planned or getting stuck at a particular point.

docker service inspect --format '{{.UpdateStatus.State}}' returns a compact status value like updating, completed or rollback_completed, which is excellent for automated checks in CI pipelines. A deployment script can poll this value in a loop and only report success once the status reaches completed, instead of blindly assuming a rolling update is done right after the command was issued.


# Poll update status until it completes or fails, useful in CI pipelines
until [ "$(docker service inspect shop_api --format '{{.UpdateStatus.State}}')" = "completed" ]; do
  state=$(docker service inspect shop_api --format '{{.UpdateStatus.State}}')
  if [ "$state" = "rollback_completed" ]; then
    echo "Update failed and rolled back" >&2
    exit 1
  fi
  sleep 3
done
echo "Rolling update completed successfully"

8. Common pitfalls with rolling updates

The most common mistake is the complete absence of a health check, which causes Docker Swarm to consider a crashing container as successfully started, as long as the process is technically still running. Without a health check, a rolling update can theoretically complete successfully, even though the new version is actually broken and not answering real requests. This gap often stays unnoticed until users report errors, because the Docker CLI itself does not raise an alarm.

A second common mistake is too short a delay combined with slow starting applications. If the application takes ten seconds to start but delay is set to five seconds, the next batch begins before the previous one is actually stable, which can cause cascading failures if an underlying problem affects all new containers equally. The combination of a generous delay, correct start_period in the health check, and enabled automatic rollback reliably covers most of these cases.

9. Update strategies side by side

The following table compares the most important configuration options for rolling updates and their impact on deployment speed and safety.

Configuration Speed Safety Recommendation
parallelism: 1 Slow Very high Critical services, small clusters
parallelism: 2 to 3 Balanced High Default recommendation for most services
order: start-first Neutral Higher, no capacity gap Stateless web applications
order: stop-first Neutral Lower on tight resources Resource constrained nodes
failure_action: rollback Neutral Automatic safeguard Always enable in production

In practice, a combination of moderate parallelism, start-first order for stateless services, and enabled automatic rollback proves to be a solid default that works for most applications without further tuning.

Mironsoft

Zero downtime deployments and Swarm deployment automation

Deployments that don't take your shop offline?

We configure rolling updates with health checks, rollback automation and fitting update strategies, so every deployment runs without a noticeable outage.

Update strategy

Configuring parallelism, delay and order to fit your application

Health checks

Meaningful health check endpoints instead of pure process checks

CI integration

Automated status checks and rollback in your deployment pipeline

10. Summary

Rolling updates in Docker Swarm enable continuous availability during deployments, provided parallelism, delay, health checks and rollback rules are configured correctly. The update_config section controls how many containers get updated at once and how long the pause between batches is, while failure_action: rollback automatically restores the previous version once too many tasks fail.

A meaningful health check is the basic prerequisite for Docker Swarm to judge the actual application state instead of just the process status. Combined with the expand contract pattern for database migrations and a well thought out update order, rolling updates can be automated safely and without a noticeable outage even for more complex applications.

Rolling updates in Docker Swarm: the essentials at a glance

Parallelism and delay

parallelism and delay control how many containers get updated at once and how long the pause between batches is.

Health checks

Without a meaningful health check, Swarm cannot distinguish a broken container from a working one.

Automatic rollback

failure_action: rollback automatically restores the previous version without manual intervention.

Database migrations

Use the expand contract pattern so old and new application versions work in parallel with the same schema.

11. FAQ: Rolling updates in Docker Swarm

1Does every service need a health check?
Not strictly, but strongly recommended, otherwise Swarm cannot detect broken containers.
2How to trigger an update manually?
docker service update --image, or re-run docker stack deploy with a changed tag.
3What happens on automatic rollback?
Update stops, previous image version restored via rollback_config.
4start-first vs stop-first?
start-first maximizes availability, stop-first saves resources on tight nodes.
5Handling database migrations?
Use the expand contract pattern, split schema changes into compatible steps.
6How to monitor progress?
docker service ps live, docker service inspect for compact status in CI pipelines.
7Can I abort a running update?
Yes, pause with --update-parallelism 0, or direct docker service rollback.
8How long should delay be?
At least as long as the full application startup, often 15 to 30 seconds.
9Does it work with only one replica?
Technically yes, but no availability benefit, at least two replicas recommended.
10Is max_failure_ratio 0 safest?
Yes, triggers a rollback already on a single failed task, strictest setting.