| |

Docker 64 🐳 Swarm Service Deployment: Tasks, Replicas, Global Mode, and Rolling Updates

A Docker Swarm service is not a container. It is a declaration of intent. When you create a service, you are telling the Swarm manager what the cluster should look like—how many instances of an image should be running, how they should be networked, and what policies govern their lifecycle. The manager then works continuously to make reality match that declaration. If a container crashes, the manager creates a replacement. If you change the declared state, the manager reconciles the difference. This reconciliation loop is the heart of Swarm’s orchestration model.

The abstraction that makes this work is the task. A task is the atomic unit of scheduling in Swarm—it is a slot that the scheduler fills with a container . When you declare a service with three replicas, the manager creates three tasks and assigns each one to a node. A task is one-directional: it progresses through states like ASSIGNED, PREPARING, and RUNNING, and if it fails, it is removed and replaced by a new task . This means you never restart a task; you reconcile the service, and the manager handles the replacement.

Swarm supports two service modes: replicated and global. Replicated services run a specified number of identical tasks, distributed across the cluster according to available resources . Global services run exactly one task on every available node, automatically adding tasks when new nodes join and removing them when nodes leave . The choice between them depends on whether you need a fixed number of instances or a presence on every machine.

This chapter covers the service deployment model in detail: how tasks are scheduled and what happens when they fail, the difference between replicated and global modes, and how rolling updates replace tasks gradually to maintain availability during image changes.

Key point: A Swarm service is a desired state declaration; the manager creates tasks to fulfill it, using replicated mode for a fixed count of instances and global mode for one task per node, with rolling updates replacing tasks incrementally according to a configurable policy.


Why tasks and services are separate concepts

The reconciliation problem. In a traditional container deployment, you run docker run and get a container. If that container dies, nothing brings it back. Swarm solves this by introducing a layer of indirection: you declare a service, and the manager creates tasks to realize it. The manager constantly compares the actual state of the cluster (which tasks are running) against the desired state (how many tasks the service declares) and takes corrective action when they diverge .

The atomic scheduling unit. A task is the smallest schedulable entity in Swarm. It carries a Docker container and the commands to run inside it. The scheduler assigns tasks to nodes based on resource availability, constraints, and placement preferences . Once a task is assigned to a node, it cannot move—it can only run on that node or fail . If it fails, a new task is created, possibly on a different node.

One-directional lifecycle. Tasks progress monotonically through states. They do not go backward. A task that reaches RUNNING does not become PREPARING again. If it fails, the task is removed and a new task is created to replace it . This design simplifies reasoning: you do not manage tasks directly; you manage services, and the manager handles tasks.

The service definition is the interface. When you create a service, you specify the image, command, ports, networks, resource limits, update policy, and number of replicas . You can change almost any of these later with docker service update, and the manager will reconcile the change by replacing tasks that have out-of-date configuration .

Pending services. If no node can satisfy a service’s requirements—because of resource constraints, placement constraints, or node availability—the service remains in a pending state . This is not an error; it is the manager waiting for a node that can run the tasks. If you specify a memory reservation larger than any node’s capacity, the service stays pending indefinitely .


a. Replicated services: a fixed number of tasks

Replicated mode is the default for Swarm services. When you create a service without specifying a mode, Swarm uses replicated mode. You specify the number of identical tasks you want running with the --replicas flag .

docker service create \
  --name web \
  --replicas 3 \
  --publish 8080:80 \
  nginx:latest

This creates a service named web with three replica tasks, each running an nginx:latest container. The manager schedules the three tasks across the available nodes, distributing them according to resource availability and any placement constraints . If you have three worker nodes, typically each gets one task. If you have two nodes, one gets two tasks and the other gets one.

The manager continuously monitors the tasks. If a node fails and its tasks become unavailable, the manager schedules replacements on other nodes. If a task crashes and exits, the manager creates a new task to replace it . The service’s replica count is maintained as the desired state, and the manager reconciles reality to match it.

You can scale a replicated service up or down with docker service scale or by updating the --replicas flag:

docker service scale web=5

This tells the manager to create two additional tasks. The manager schedules them on nodes with available capacity. When you scale down, the manager removes tasks, stopping their containers gracefully.

Replicated mode is appropriate when you need a specific number of instances—web servers behind a load balancer, worker processes consuming from a queue, or any workload where the replica count is a meaningful configuration parameter .


b. Global services: one task per node

Global mode changes the scheduling model entirely. Instead of a fixed replica count, a global service runs exactly one task on every available node that matches the service’s placement constraints .

docker service create \
  --name monitoring-agent \
  --mode global \
  monitoring-agent:1.0

When you create a global service, the manager places one task on every active node. When a new node joins the Swarm, the manager automatically schedules a task for the global service on that node . When a node leaves, its task is removed and not rescheduled elsewhere .

Global mode is designed for infrastructure services that need a presence on every machine. Monitoring agents, log collectors, security scanners, and network daemons are classic examples . A monitoring agent that runs on every node can collect metrics from that node’s containers; if it ran only on a subset of nodes, the metrics would be incomplete.

Global services do not take a --replicas flag. The number of tasks is determined by the number of nodes, not by a configuration value. If you try to specify both --mode global and --replicas, the command fails.

Placement constraints work with global mode but in a different way than with replicated mode. With a replicated service, a constraint tells the scheduler which nodes are eligible for tasks, but not every eligible node gets one. With a global service, a constraint filters the nodes: only nodes matching the constraint get a task . For example, a global service with the constraint node.labels.type==edge would run one task on every node labeled as an edge node, and no tasks on other nodes.


c. Rolling updates: replacing tasks incrementally

A rolling update replaces a service’s tasks gradually, maintaining availability throughout the process. Instead of stopping all tasks at once, the manager stops one task (or a batch of tasks), starts a replacement with the new configuration, waits for it to become healthy, and then proceeds to the next .

The update policy is configured at service creation time or updated later. The key parameters are:

  • --update-parallelism: How many tasks to update simultaneously. The default is 1 . Setting this to 2 or 3 speeds up the update but temporarily reduces capacity by that many tasks.
  • --update-delay: How long to wait after a task reaches RUNNING before updating the next task. The default is 0 seconds. A delay like 10s or 30s gives the new task time to stabilize before proceeding .
  • --update-failure-action: What to do when a task fails to update. The default is pause, which halts the update for investigation. Other options are continue (ignore the failure and proceed) and rollback (revert to the previous configuration) .
  • --update-monitor: How long to monitor a new task before considering it healthy. The default is 30 seconds .
  • --update-max-failure-ratio: The fraction of tasks that can fail before the update is considered failed. Default is 0 .

The update process follows a defined sequence :

  1. Stop the first task.
  2. Schedule the replacement task with the new configuration.
  3. Start the container for the new task.
  4. If the new task reaches RUNNING, wait for the delay period, then proceed to the next task.
  5. If any task returns FAILED, pause the update (or take the configured failure action).

During the update, docker service ps shows a mix of tasks running the old and new versions. This mixed state is expected and temporary . Once all tasks are updated, the service returns to a uniform state.

You trigger a rolling update by changing the service’s image:

docker service update --image nginx:1.27 web

Or by changing any other configuration parameter. The manager detects the change and applies the update policy.

If an update fails and pauses, you can investigate the failed tasks with docker service ps. To resume, run docker service update web (which restarts the paused update). To roll back, use docker service update --rollback web . The rollback restores the service to the configuration that was in place before the most recent update command .

Automatic rollback can be configured with --update-failure-action=rollback. When a task fails during an update, the manager automatically reverts to the previous configuration . This is useful for production services where manual intervention is undesirable.


Complete Example Session

The following session demonstrates deploying a replicated service, deploying a global service, and performing a rolling update with a delay and failure action.

# ============================================
# PART 1: CREATE A REPLICATED SERVICE
# ============================================
docker service create \
  --name web \
  --replicas 4 \
  --publish 8080:80 \
  --update-delay 10s \
  --update-parallelism 1 \
  --update-failure-action pause \
  nginx:1.27.0

# ============================================
# PART 2: VERIFY THE SERVICE
# ============================================
docker service ls
# Shows: web, replicated, 4/4

docker service ps web
# Shows four tasks distributed across nodes

# ============================================
# PART 3: CREATE A GLOBAL SERVICE
# ============================================
docker service create \
  --name node-monitor \
  --mode global \
  monitoring-agent:1.0

# ============================================
# PART 4: VERIFY THE GLOBAL SERVICE
# ============================================
docker service ps node-monitor
# Shows one task per node

# ============================================
# PART 5: TRIGGER A ROLLING UPDATE
# ============================================
docker service update \
  --image nginx:1.27.1 \
  web

# The manager updates tasks one at a time
# with a 10-second delay between each

# ============================================
# PART 6: WATCH THE UPDATE PROGRESS
# ============================================
docker service ps web
# Shows a mix of nginx:1.27.0 and nginx:1.27.1
# tasks during the update

# ============================================
# PART 7: INSPECT THE UPDATE STATUS
# ============================================
docker service inspect web --pretty
# Look for "UpdateStatus" section

# ============================================
# PART 8: SCALE THE SERVICE
# ============================================
docker service scale web=6
# Manager creates two additional tasks

# ============================================
# PART 9: ROLL BACK IF NEEDED
# ============================================
# If the new image has problems:
docker service update --rollback web
# Reverts to nginx:1.27.0

# ============================================
# PART 10: CLEAN UP
# ============================================
docker service rm web
docker service rm node-monitor

The ten parts cover replicated service creation with an update policy, verification, global service deployment, triggering a rolling update by changing the image, watching the mixed-version state during update, inspecting update status, scaling, rollback, and cleanup. What the session demonstrates is that Swarm services are declarative: you specify the desired state, and the manager reconciles tasks to match it, including during updates.


Quick Reference

Service Modes

ModeFlagBehaviorUse Case
Replicated--replicas NFixed number of tasksWeb servers, workers
Global--mode globalOne task per nodeMonitoring, logging agents

Task States

StateMeaning
NEWTask created, not yet assigned
ASSIGNEDAssigned to a node
PREPARINGNode preparing to run task
RUNNINGContainer running
COMPLETETask finished successfully
FAILEDTask failed
SHUTDOWNTask stopped

Rolling Update Flags

FlagDefaultPurpose
--update-parallelism1Tasks updated simultaneously
--update-delay0sWait between task updates
--update-failure-actionpauseAction on failure (pause/continue/rollback)
--update-monitor30sTime to monitor task after start
--update-max-failure-ratio0Fraction of failures tolerated

Rollback Flags

FlagDefaultPurpose
--rollback—Trigger manual rollback
--rollback-parallelism1Tasks rolled back simultaneously
--rollback-delay0sWait between rollback tasks
--rollback-failure-actionpauseAction on rollback failure

Best Practices

✅ Do This:

docker service create --replicas 3 --update-delay 10s web  # ✅ delay for stability
docker service create --mode global --name agent agent:1.0 # ✅ global for agents
docker service update --image app:2.0 --update-failure-action rollback web # ✅ auto rollback
docker service ps web                                      # ✅ verify task distribution

❌ Don’t Do This:

docker service create --mode global --replicas 3 agent      # ❌ incompatible flags
docker service update --image app:2.0 web                  # ❌ no failure policy
# ignore "pending" service                                 # ❌ check constraints/resources
# scale to 0 instead of drain                              # ❌ for maintenance use drain

Common Pitfalls

PitfallWhy It HappensFix
Service stuck in pendingNo node satisfies constraints/resourcesCheck placement constraints and reservations
Global service not on all nodesNode drained or constraint mismatchCheck node availability and labels
Rolling update pausesNew task fails to startCheck logs, fix image, resume or rollback
Update too slowLow parallelism, high delayIncrease parallelism or reduce delay
Mixed versions during updateExpected behaviorWait for update to complete
Rollback failsPrevious config also problematicInvestigate root cause, fix, redeploy

Real-World Examples

1. Web service with rolling updates

docker service create --replicas 4 --update-delay 10s --update-parallelism 2 nginx

2. Monitoring agent on every node

docker service create --mode global --name node-exporter prom/node-exporter

3. Rolling update with automatic rollback

docker service update --image app:2.0 --update-failure-action rollback app

4. Scale a service

docker service scale web=8

5. Manual rollback

docker service update --rollback web

6. Update with no delay

docker service update --image app:2.0 --update-delay 0s app

7. Global service with constraint

docker service create --mode global --constraint 'node.labels.type==edge' edge-agent

8. Update parallelism

docker service update --update-parallelism 3 --image app:2.0 app

9. Inspect update status

docker service inspect web --format '{{.UpdateStatus.State}}'

10. Remove a service

docker service rm web

Visual

Replicated vs Global Services

┌──────────────────────────────────────────────┐
│  REPLICATED SERVICE (--replicas 3)           │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐       │
│  │ Node 1  │  │ Node 2  │  │ Node 3  │       │
│  │ Task A  │  │ Task B  │  │ Task C  │       │
│  └─────────┘  └─────────┘  └─────────┘       │
│  Fixed count, distributed by scheduler       │
│                                              │
│  GLOBAL SERVICE (--mode global)              │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐       │
│  │ Node 1  │  │ Node 2  │  │ Node 3  │       │
│  │ Task    │  │ Task    │  │ Task    │       │
│  └─────────┘  └─────────┘  └─────────┘       │
│  One per node, automatic on join/leave       │
└──────────────────────────────────────────────┘

Rolling Update Sequence

┌──────────────────────────────────────────────┐
│  INITIAL STATE: 4 tasks running v1.0         │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐             │
│  │ v1  │ │ v1  │ │ v1  │ │ v1  │             │
│  └─────┘ └─────┘ └─────┘ └─────┘             │
│                                              │
│  STEP 1: Stop task 1, start v2               │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐             │
│  │ v2  │ │ v1  │ │ v1  │ │ v1  │             │
│  └─────┘ └─────┘ └─────┘ └─────┘             │
│         wait delay, monitor v2               │
│                                              │
│  STEP 2: Stop task 2, start v2               │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐             │
│  │ v2  │ │ v2  │ │ v1  │ │ v1  │             │
│  └─────┘ └─────┘ └─────┘ └─────┘             │
│                                              │
│  ... repeat until all tasks updated          │
│                                              │
│  FINAL STATE: 4 tasks running v2.0           │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐             │
│  │ v2  │ │ v2  │ │ v2  │ │ v2  │             │
│  └─────┘ └─────┘ └─────┘ └─────┘             │
└──────────────────────────────────────────────┘

Task Lifecycle

┌──────────────────────────────────────────────┐
│  NEW                                         │
│   │                                          │
│   ▼                                          │
│  ASSIGNED ──▶ PREPARING ──▶ RUNNING          │
│                              │               │
│                    ┌─────────┴─────────┐     │
│                    │                   │     │
│                    ▼                   ▼     │
│                 COMPLETE            FAILED   │
│                                      │       │
│                                      ▼       │
│                              task removed,   │
│                              new task created│
│                              (reconciliation)│
└──────────────────────────────────────────────┘

Update Failure Actions

┌──────────────────────────────────────────────┐
│  pause (default)                             │
│  Update halts, mixed versions remain         │
│  Operator investigates and resumes           │
│                                              │
│  continue                                    │
│  Failed task ignored, update proceeds        │
│  Risk: cluster left in mixed-version state   │
│                                              │
│  rollback                                    │
│  Update reverts to previous configuration    │
│  Failed new tasks replaced with old version  │
└──────────────────────────────────────────────┘

Summary

ItemValue
ServiceDesired state declaration
TaskAtomic scheduling unit, one per container
Replicated modeFixed number of tasks
Global modeOne task per node
Rolling updateIncremental task replacement
Update parallelismTasks updated simultaneously (default 1)
Update delayWait between task updates (default 0s)
Failure actionpause, continue, or rollback
RollbackRevert to previous configuration
Pending serviceNo node satisfies requirements

Key takeaways:

  • A service is a desired state, not a container. You declare what the cluster should look like, and the manager reconciles tasks to match .
  • A task is the atomic scheduling unit. It carries one container and progresses through a one-directional lifecycle. Failed tasks are replaced, not restarted .
  • Replicated mode runs a fixed count. You specify --replicas N, and the manager distributes N tasks across available nodes .
  • Global mode runs one task per node. It is designed for agents that need a presence on every machine, and it automatically adapts as nodes join and leave .
  • Rolling updates replace tasks gradually. The default is one task at a time with no delay, but you can configure parallelism, delay, and failure handling .
  • Failure action determines what happens when an update fails. pause halts for investigation, continue ignores the failure, and rollback reverts automatically .
  • Rollback restores the previous configuration. It can be triggered manually with --rollback or automatically via --update-failure-action=rollback .
  • Pending services are waiting for capacity. If no node can satisfy the service’s constraints or resource requirements, the service remains pending until one becomes available .

Remember: Docker Swarm services are built on the separation of declaration and execution. You declare a service—its image, replica count, mode, and update policy—and the manager creates tasks to realize that declaration. Tasks are the atomic units: they run on nodes, they progress through states, and they are replaced when they fail. Replicated mode gives you a fixed count; global mode gives you one per node. Rolling updates replace tasks incrementally, with configurable parallelism, delay, and failure handling, so that a new version can be deployed without taking the service offline. The manager reconciles continuously: whatever you declare, it works to make true.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!