Introduction
Docker Swarm is both a secure cluster of Docker nodes and an intelligent application orchestrator. While Kubernetes has become the dominant orchestration platform, Swarm remains a lightweight alternative well suited to smaller environments that don't need the complexity and learning curve of a full Kubernetes setup.
Managers and Workers
A swarm consists of manager nodes, which run control plane services and orchestration logic, and optional worker nodes, which run application workloads. Both types can be physical machines, VMs, or cloud instances, as long as they run Docker and can communicate reliably over the network. By default, managers also run application workloads, though production environments often dedicate them purely to control plane duties.
Building a Swarm
A swarm is initialized on the first intended manager node:
docker swarm initThis command outputs a docker swarm join command containing a token, which can be run on other nodes to add them as workers:
docker swarm join --token SWMTKN-1-... 172.31.40.192:2377For high availability, production swarms typically run three managers so the cluster can tolerate the loss of one. A separate join token for managers can be generated with:
docker swarm join-token managerThe state of the cluster can be checked at any time with:
docker node lsOne manager is always shown as Leader, with the others marked Reachable, reflecting Swarm's active/passive high-availability model.
Deploying an App
Swarm apps are defined using a Compose file, extended with Swarm-specific deploy settings such as replica counts, update behavior, and restart policies. A typical service definition might request four replicas, update two at a time with a delay between batches, and roll back automatically on failure.
The core concept behind Swarm is desired state — what the Compose file specifies the app should look like. Deploying an app is done with:
docker stack deploy -c compose.yaml dddSwarm then works to make the cluster's observed state match this desired state, distributing replicas evenly across available nodes. The status of a deployed app can be checked with:
docker stack ps ddd
docker stack services dddManaging Apps Declaratively
Swarm apps can be managed either imperatively, by running direct CLI commands, or declaratively, by editing the Compose file and redeploying. The declarative approach is strongly preferred, since imperative changes — like manually scaling a service — can be silently overwritten the next time the Compose file is redeployed, since Swarm always reconciles the cluster back to what the file describes.
Updating an app, such as scaling replicas and switching to a new image version, is done entirely by editing the Compose file and re-running:
docker stack deploy -c compose.yaml dddSwarm then performs a controlled rolling update, replacing replicas in batches according to the rules defined under deploy.update_config, and rolling back automatically if failures occur.
Cleaning Up
An app can be removed with:
docker stack rm dddNote that this removes services and networks but not volumes, since Swarm intentionally decouples volume lifecycles from the app itself, requiring an explicit docker volume rm to delete stored data.
Conclusion
Docker Swarm offers a genuinely capable, if less popular, way to run highly available, self-healing microservices applications across a cluster of nodes. Managing everything declaratively through Compose files — kept under version control — ensures the cluster's actual state always reflects what's intended, and makes Swarm a practical stepping stone toward learning more advanced orchestration platforms like Kubernetes.