Joining many servers into a single cluster with Docker's built-in Swarm Mode: understanding the manager and worker architecture, Raft consensus and quorum, initializing a cluster with docker swarm init/join, node management, and when to choose Swarm over Kubernetes.

After building observability in episode 15 — rotated logging drivers, HEALTHCHECK, metrics, and the cAdvisor + Prometheus + Grafana stack — you can now see a single node completely. But there's a limit that monitoring can't leap over: a single node is still a single point of failure. Once the application grows beyond one server's capacity, or one server dies and every container in it dies with it, we need something bigger: a group of servers working as one unit — and that is the essence of orchestration.
Imagine a single host as one house holding all family members. Practical while the family is small. But when members grow, one house is no longer enough: you need a housing complex with many houses, a manager deciding who lives in which house, and a rule that if one house breaks, its residents move to another. The orchestrator is that complex's manager, and Docker Swarm Mode is the manager already embedded in the Docker Engine — no extra installation.
Why is this topic important to master? Because scale is an unavoidable direction: staging that used to be one node starts needing two, then five. Understanding Swarm gives you a mental model of clusters and orchestration that also applies to Kubernetes (we'll discuss the comparison shortly), and — more practically — Swarm is the cheapest and simplest way to bring Docker to many hosts without building your own platform. In this episode we'll dissect what Swarm Mode is, when to choose it over Kubernetes, break down the manager/worker architecture, then practice cluster initialization, join tokens, and node management in full.
Swarm Mode is Docker Engine's built-in operating mode for clustering and orchestration. The moment you type docker swarm init on a node, that node stops working alone — it becomes part of a swarm (group), and all joining nodes can run and manage containers collectively.
The phrase "built-in" isn't just about the convenience of no installation. It means there are no extra components to maintain: no separate API server, no additional state database, no external agent. The entire control-plane — the components that make decisions about what runs where — lives inside the Docker daemon itself. For teams that don't want to build a large orchestration platform, this is a luxury: production-grade features (services, rolling updates, secrets, multi-host load balancing) are available just by enabling a mode that was already right in front of you.
When Swarm and when Kubernetes? This isn't a "which is more powerful" question, but "which fits your workload":
| Aspect | Docker Swarm | Kubernetes |
|---|---|---|
| Installation & operation | Built-in, one-command initialization | Needs control-plane + worker installation (kubeadm, k3s, etc.) |
| Complexity | Low — few concepts, fast results | High — many components (etcd, scheduler, controller, etc.) |
| Advanced features | Services, secrets, overlay, rolling updates | Advanced autoscaling, CRDs, operators, service mesh, etc. |
| Ecosystem | Small but focused | Massive — every cloud vendor supports it |
| Time from learning to value | Hours | Weeks |
| Ideal for | Small teams, straightforward container workloads, batch, simple migrations | Large platforms, multi-team, complex stateful workloads, wide ecosystem |
A useful mental model: Swarm is orchestration running "on the edge" of Docker — you keep writing the things you know (services, networks, volumes) with familiar syntax. Kubernetes is a platform of its own with its own philosophy and tooling. Many teams start with Swarm for basic needs, then move to Kubernetes when they need features that can't be patched in. Understanding Swarm first makes the transition to Kubernetes much smoother because the underlying concepts are the same: declared state, a scheduler, and workers.
A swarm consists of two types of nodes:
Manager Nodes are the cluster's brain. They run Raft consensus to store the cluster state (what services exist, how many replicas, on which node they run), schedule tasks to workers, and serve the API. Every important decision — a node joining, a service created, a task assigned — is recorded in a state store synchronized among managers.
Worker Nodes are the cluster's muscle. They don't make decisions; they simply run tasks (units of work, i.e. containers) assigned by managers. A node can be a manager and run tasks at the same time — this is actually common in small clusters.
The most important design decision sits in Raft consensus. Raft is the algorithm that ensures all managers agree on the same state, even if some managers die. The key is quorum — a majority of managers must be alive and agreeing for the cluster to keep making decisions:
Rule of thumb: the number of managers must be odd. 2 managers give the same tolerance as 1 (you need 2 of 2 for quorum) — so better to have 3 or 1. Raft is like a board meeting that's only valid if a majority attends: a board of 3 can continue if 1 is absent, a board of 2 can't continue without both.
Tip
The more managers, the more Raft processes need to be synchronized — and the heavier the overhead. For most workloads, 3 managers is the sweet spot. Only expand to 5 if you truly need tolerance for 2 dead nodes (usually only for very large clusters). Workers can be added without limit — no quorum constraints.
Everything starts with one command on the node that will be the first manager. The --advertise-addr flag tells other nodes which address to use to reach this manager — required in multi-interface or cloud environments:
docker swarm init --advertise-addr 10.0.0.11Swarm initialized: current node (abcd12ef34gh) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-xxxx... 10.0.0.11:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.Note two things in the output: the join command is already provided, and there are two paths — one for workers and one for managers. That visible token is a secret (we'll cover it in the security section). Node-1 is now a sole manager: that's fine, but remember the quorum story — for production, aim for 3 managers.
To add a worker on node-2 (IP 10.0.0.12), run the join command generated earlier. To add a second manager, request the manager token from a node that's already a manager:
docker swarm join-token worker
docker swarm join-token managerdocker swarm join --token SWMTKN-1-xxxx... 10.0.0.11:2377This node joined a swarm as a worker.Important
Store the join token as a guarded secret. Anyone holding the token can join the cluster and run containers inside it — or take part in state decisions. Periodic token rotation (docker swarm join-token --rotate worker) is a healthy security habit, especially after a node retires.
The same join command is used to add a manager — just with the manager token. The execution flow: the new node contacts an existing manager at IP:2377, proves token ownership, then the new node re-syncs cluster state from the manager (Raft). This is why port 2377 must be open between nodes — we cover the port list at the end.
From any manager, view all nodes and their roles:
docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
abcd12ef34gh * node-1 Ready Active Leader 27.1.1
ijkl56mn78op node-2 Ready Active Reachable 27.1.1
qrst90uv12wx node-3 Ready Active Reachable 27.1.1
yzas12bc34de node-4 Ready Active 27.1.1The MANAGER STATUS column marks the role: Leader (the manager currently leading Raft), Reachable (other managers participating in quorum), and empty means a worker. The AVAILABILITY column (Active/Drain/Pause) controls whether a node accepts new tasks.
Nodes aren't permanent — their role and availability can be changed:
docker node promote node-4docker node demote node-3Drain is the most important mode for maintenance: it makes the node stop accepting new tasks and moves running tasks to other nodes — exactly how you do server maintenance without service downtime:
docker node update --availability drain node-2
# ... maintenance selesai, kembalikan node ke layanan
docker node update --availability active node-2docker node update --availability pause is a gentler variant: the node stops accepting new tasks but existing tasks keep running — useful when you want to "freeze" a node without disturbing running containers. Understand the usage order: drain for full maintenance, pause for a temporary hold, active to bring a node back into service.
Swarm secures inter-node communication with automatic TLS. Every node gets a certificate signed by the swarm's internal CA, and that certificate rotates every 90 days automatically. That means: all traffic between managers and workers — including service secrets — is encrypted in transit, with no extra configuration. This is a layer often missed when people praise Swarm's "simplicity": transport security that needs extra setup in Kubernetes is already on from the first join in Swarm.
The two join tokens (worker and manager) are the cluster's access keys. The manager token is naturally more sensitive than the worker token — holding the manager token means you could co-lead the cluster. Periodic rotation and revoking nodes you no longer trust (docker node rm <id>) are two habits that must be on a production checklist.
Networking is the most common reason "swarm works on one node but not many nodes". The following three ports must be reachable between all nodes in the cluster:
| Port | Protocol | Function |
|---|---|---|
2377 | TCP | Control-plane: join, tokens, Raft communication between managers |
7946 | TCP & UDP | Gossip protocol: information spread between nodes |
4789 | UDP | VXLAN for overlay networks (cross-node container communication) |
Warning
Most "worker joined but containers can't talk to each other" problems come from blocked ports 4789/udp or 7946. In the cloud, make sure the security group/firewall allows all three — for inter-node communication, not just from outside. Test with nc -zv <ip> 2377 after configuring the firewall.
A summary of the cluster setup sequence in one code-group — from the first node to the fourth:
# Node-1 (manager Leader)
sudo ufw allow 2377/tcp && sudo ufw allow 7946/tcp && sudo ufw allow 7946/udp && sudo ufw allow 4789/udp
docker swarm init --advertise-addr 10.0.0.11With two managers, Raft quorum can survive one dying — but remember the odd-number rule: for real HA aim for 3 managers.
--advertise-addr wrong or ignored. On hosts with many interfaces or cloud NAT, without this flag a node can advertise an address other nodes can't reach. Always set it explicitly.Ready but overlay traffic stalls, or cross-node containers can't talk. Check the cloud firewall first.docker node rm for retiring nodes are mandatory habits.drain before shutting down a server for maintenance, so tasks migrate and services stay undisturbed.In this episode 16 we joined several servers into one cluster: understanding that Swarm Mode is Docker's built-in orchestration with a far lower complexity trade-off than Kubernetes, dissecting the manager (brain: Raft consensus, state store, scheduler) and worker (muscle: running tasks) architecture, learning that quorum demands an odd number of managers with a minimum of 3 for HA, initializing the cluster with docker swarm init --advertise-addr, adding nodes with docker swarm join --token, managing roles via promote/demote/drain, understanding automatic TLS encryption, and securing communication by opening ports 2377/7946/4789.
Core takeaways:
IP:2377; inter-node TLS is automatically encrypted.drain for maintenance without downtime; promote/demote to change node roles.2377/tcp, 7946/tcp+udp, 4789/udp must be open between nodes.The cluster is standing, but it's still empty — not a single "house" (container) has been placed. In the next episode, episode 17, we'll fill it: Service Deployment, Stacks & Rolling Updates in Swarm — defining services with replica counts, deploying full applications from stack files, leveraging cross-node overlay networks, storing secrets with Swarm secrets, and releasing new versions without downtime through rolling updates and rollbacks. See you in episode 17!