What is Docker Swarm?
Docker Swarm is Docker's native, built-in cluster orchestrator. Out of the box, every Docker installation can become a manager or worker node in a Swarm cluster — no separate install, no separate CLI. The price for the simplicity is a smaller ecosystem and slower development compared to Kubernetes.
Theory
TL;DR
- Swarm = a cluster of Docker hosts working as one. Built into the Docker engine since 1.12 (2016).
- Architecture: managers (raft consensus, control plane) + workers (run containers).
- Services:
docker service createdeclares the desired state (image, replicas, ports, network); Swarm schedules tasks (running containers) to satisfy it. - Built-in features: service discovery (via overlay network DNS), routing mesh (any node can receive traffic for any service), rolling updates, restart policies, encrypted overlay networks, secrets.
- Honest assessment in 2026: Swarm works and is genuinely simpler than K8s, but new production projects almost always choose Kubernetes. Use Swarm for small clusters, on-prem, or where K8s is genuinely overkill.
Architecture
+-----------+ +-----------+ +-----------+
| manager 1 | <-> | manager 2 | <-> | manager 3 | (raft)
+-----------+ +-----------+ +-----------+
^ ^ ^
| | |
| gossip / control plane |
| |
+-----------+ +-----------+ +-----------+
| worker A | | worker B | | worker C |
| (tasks) | | (tasks) | | (tasks) |
+-----------+ +-----------+ +-----------+- Managers form a raft quorum. Odd number recommended (3, 5, 7) for fault tolerance. Lose majority → cluster cannot accept new operations.
- Workers run tasks. Cannot make scheduling decisions; just execute what managers tell them.
- A node can be both manager and worker simultaneously (
--availability=active). Small clusters often have 3 managers that are also workers.
Core concepts
Service
Declarative description of a workload. Like a Kubernetes Deployment.
docker service create \
--name api \
--replicas 5 \
--publish 80:80 \
--network appnet \
--update-parallelism 2 \
--update-delay 10s \
--restart-condition on-failure \
--restart-max-attempts 5 \
myorg/api:1.2.0Task
A running instance of a service. If --replicas 5, the service has 5 tasks. Each task is a single container running on one node. If a task dies, Swarm spawns a new one.
Node
A machine in the cluster. Either manager or worker (or both). Each node has labels you can target with placement constraints (--constraint node.labels.tier==edge).
Stack
A group of services deployed together via a Compose file. docker stack deploy -c compose.yaml mystack.
Setting up a Swarm cluster
# On node-1 (will be the manager)
node-1$ docker swarm init --advertise-addr 192.168.1.10
Swarm initialized: current node (xxx) is now a manager.
To add a worker, run: docker swarm join --token SWMTKN-... 192.168.1.10:2377
# On node-2 (worker)
node-2$ docker swarm join --token SWMTKN-... 192.168.1.10:2377
# Back on manager
node-1$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xxx node-1 Ready Active Leader
yyy node-2 Ready ActiveTwo commands and you have a working cluster. Compare with Kubernetes' kubeadm init + CNI install + storage class setup + RBAC tuning.
Routing mesh and service discovery
When you publish a service port:
docker service create --name api --publish 80:80 --replicas 3 myappSwarm creates an ingress overlay network that all nodes participate in. Any node can receive traffic on port 80, even if no replica runs there — the routing mesh forwards to a healthy task.
Services on the same overlay network resolve each other by name:
# Inside any task on appnet
$ nslookup api
Name: api
Address: 10.0.0.5 # virtual IP, IPVS-balanced across replicasThe service name resolves to a virtual IP; kernel IPVS load-balances across healthy replicas.
Updating and scaling
# Scale
docker service scale api=10
# Rolling update
docker service update --image myorg/api:1.3.0 api
# Honors --update-parallelism, --update-delay, --update-failure-action
# Rollback
docker service rollback apiRolling updates are first-class: change one parallelism slice at a time, wait, verify health, continue or roll back automatically.
Stacks via Compose
# stack.yaml
services:
api:
image: myorg/api:1.2.0
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
order: start-first
restart_policy:
condition: on-failure
placement:
constraints: [node.role == worker]
networks: [appnet]
web:
image: nginx:1.27-alpine
ports: ["80:80"]
networks: [appnet]
networks:
appnet:
driver: overlaydocker stack deploy -c stack.yaml mystack
docker stack services mystack
docker stack ps mystack
docker stack rm mystackSwarm's stack format is largely compatible with Compose (with deploy: keys honored only in Swarm).
Honest comparison with Kubernetes (2026)
| Swarm | Kubernetes | |
|---|---|---|
| Setup | docker swarm init | kubeadm init + CNI + storage + ingress |
| Learning curve | a weekend | months |
| Manifest format | Compose-flavored YAML | k8s YAML (verbose) |
| Ecosystem | small, mostly Docker Inc | enormous (CNCF, vendors, community) |
| Multi-tenant | weak | strong (namespaces, RBAC, quotas) |
| Maintained | yes, but feature-frozen | actively developed |
| Use today for | small clusters, edge, simplicity | almost everything else |
The 2026 reality: most production teams pick Kubernetes. Swarm is alive but not the default. Cloud providers have stopped emphasizing managed Swarm; managed K8s (EKS, GKE, AKS) is everywhere.
Common mistakes
Treating Swarm like Compose
Most Compose features work, but Swarm-specific keys (deploy.placement, deploy.update_config, deploy.replicas) are honored only in Swarm. docker compose up ignores them.
Running with one manager
A single manager has no fault tolerance. Lose it → cluster is unrecoverable. Always 3 managers minimum for production.
Forgetting that bind mounts do not span nodes
A task scheduled on node-2 cannot read a bind mount from node-1's filesystem. Use volumes with networked drivers (NFS, EBS) for stateful workloads, or pin tasks to specific nodes.
Routing mesh hiding source IP
The ingress mesh DNATs incoming traffic. Your app sees the Swarm node's IP, not the client's. Use --publish mode=host if you need real client IPs (sacrifices the mesh's any-node receiving).
Real-world usage
- Small on-prem clusters: 5-20 nodes. Swarm's simplicity beats K8s setup pain.
- Edge / IoT: lightweight orchestration for small fleets.
- Low-resource environments: Swarm has lower overhead than full K8s.
- Internal tools, side projects: when you do not need K8s' depth.
Follow-up questions
Q: Should I learn Swarm in 2026?
A: As your only orchestrator, no — career-wise, Kubernetes is the dominant skill. As a stepping stone or for a small specific use case, sure. Concepts (services, tasks, declarative state, rolling updates) transfer to K8s anyway.
Q: Can Swarm and Kubernetes run on the same nodes?
A: Technically yes (different ports, different namespaces), but it is fragile and a maintenance burden. Pick one orchestrator per cluster.
Q: What is the difference between a Service and a Task?
A: Service is the declaration ("I want 5 replicas of myapp:1.0"). Tasks are the running instances that satisfy the declaration. Swarm reconciles: if the desired state says 5 and only 4 are running, it spawns one more.
Q: How does Swarm handle storage?
A: Local volumes per node (work for stateless or single-node-pinned services), or volume drivers (NFS, REX-Ray, AWS EBS plugins) for portable storage. Real production storage on Swarm is usually external (managed DB, object storage), not local volumes.
Q: (Senior) Why has Swarm lost ground to Kubernetes despite being simpler?
A: Network effects + ecosystem. K8s has Helm, Operators, Istio, Prometheus, Argo, Crossplane, thousands of vendor integrations. Swarm has the basics, well-implemented, and stops there. For complex multi-tenant production, the K8s ecosystem solves problems Swarm has no answer for. Swarm wins on simplicity if simplicity is what you need; K8s wins everywhere else by virtue of mass adoption.
Examples
Bootstrap a 3-node Swarm
# Manager + 2 workers
node-1$ docker swarm init --advertise-addr 192.168.1.10
# (note the join token from output)
node-2$ docker swarm join --token SWMTKN-... 192.168.1.10:2377
node-3$ docker swarm join --token SWMTKN-... 192.168.1.10:2377
node-1$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xxx node-1 Ready Active Leader
yyy node-2 Ready Active
zzz node-3 Ready ActiveDeploy a service spread across the cluster
node-1$ docker network create -d overlay appnet
node-1$ docker service create \
--name api \
--replicas 6 \
--network appnet \
--publish 80:80 \
--update-parallelism 2 \
--update-delay 10s \
--restart-condition on-failure \
myorg/api:1.0
node-1$ docker service ps api
# 6 tasks distributed across node-1, node-2, node-3
# All reachable on any node's port 80 via the routing meshStack from Compose-style file
node-1$ docker stack deploy -c stack.yaml mystack
Creating network mystack_appnet
Creating service mystack_api
Creating service mystack_web
node-1$ docker stack services mystack
ID NAME REPLICAS IMAGE
... mystack_api 3/3 myorg/api:1.2.0
... mystack_web 1/1 nginx:1.27-alpineOne file, one command, multi-host deployment. The simplicity Swarm fans love.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.
Comments
No comments yet