Docker Swarm

Docker Swarm is Docker's native container orchestration and cluster management solution. It aggregates multiple Docker hosts into a single virtual cluster, allowing operators to deploy, manage, and scale containerized applications as if they were working on one machine. Since Docker 1.12, Swarm Mode has been built directly into Docker Engine, so there is no need to install separate components to get started.

Compared with Kubernetes, Swarm offers a gentler learning curve and a lighter operational footprint. It is well suited to small and medium-sized clusters, rapid prototyping, and any scenario where operational simplicity is a priority. Out of the box, Swarm supports service discovery, load balancing, rolling updates, secret management, and node fault tolerance.

Core Concepts

Before working with Swarm, it helps to understand its primary objects:

  • Node: A Docker host participating in the cluster. Nodes are divided into managers and workers. Managers handle cluster management, scheduling, and API requests, while workers execute tasks.
  • Service: The definition of an application, specifying the container image, replica count, port mappings, networking, and related settings. A service is the scheduling unit in Swarm.
  • Task: A concrete container instance created when a service is scheduled. Each replica corresponds to one task.
  • Stack: A group of related services, typically defined in a Compose file and deployed with a single command.
  • Overlay Network: A virtual network that spans multiple hosts, allowing containers on different nodes to communicate with each other.

Initializing a Swarm Cluster

On the machine intended to act as the manager, run:

docker swarm init --advertise-addr 192.168.1.10

After initialization, Docker prints a join token and the command other nodes can use to enter the cluster. If no address is specified, Docker automatically selects an available network interface.

To inspect the current state of the cluster:

docker node ls

Adding Worker Nodes

On each target machine, execute the join command produced during initialization:

docker swarm join --token SWMTKN-1-xxxxxx 192.168.1.10:2377

If the token is lost, it can be regenerated from an existing manager:

docker swarm join-token worker
docker swarm join-token manager

To promote a worker to manager:

docker node promote <NODE_ID>

Deploying Services

The docker service create command quickly launches a service:

docker service create \
  --name web \
  --replicas 3 \
  --publish published=8080,target=80 \
  nginx:alpine

This example starts three Nginx replicas and maps port 8080 on any cluster node to port 80 inside the containers. Swarm's built-in routing mesh forwards traffic arriving at any node's port 8080 to an available replica.

List services and inspect their tasks:

docker service ls
docker service ps web

Scaling and Rolling Updates

Change the replica count with:

docker service scale web=5

To update the image and control the rollout:

docker service update \
  --image nginx:1.25-alpine \
  --update-parallelism 2 \
  --update-delay 10s \
  web
  • --update-parallelism: Number of replicas updated simultaneously.
  • --update-delay: Wait time between update batches.

If an update causes problems, roll back to the previous version:

docker service rollback web

Deploying Multi-Service Applications with Stacks

For applications composed of multiple services, a Stack is the preferred approach. Create a docker-compose.yml file:

version: "3.8"

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
    networks:
      - appnet

  redis:
    image: redis:7-alpine
    deploy:
      replicas: 1
    networks:
      - appnet

networks:
  appnet:
    driver: overlay

Deploy the stack:

docker stack deploy -c docker-compose.yml myapp

Inspect services and tasks within the stack:

docker stack services myapp
docker stack ps myapp

Remove the stack when it is no longer needed:

docker stack rm myapp

Networking and Load Balancing

Swarm provides two load-balancing mechanisms:

  • Internal load balancing: Through overlay networks and virtual IPs, services can reach one another by service name, and Swarm distributes requests across replicas automatically.
  • External load balancing: By publishing ports with --publish and relying on the routing mesh, inbound traffic can enter through any node.

Create a custom overlay network:

docker network create --driver overlay --attachable mynet

The --attachable flag allows standalone containers to join the network, which is useful for debugging.

Common Operational Commands

  • docker node ls: List cluster nodes.
  • docker node inspect <NODE>: Show detailed node information.
  • docker node update --availability drain <NODE>: Drain a node, moving its tasks elsewhere; commonly used before maintenance.
  • docker service logs -f <SERVICE>: Stream service logs.
  • docker service inspect --pretty <SERVICE>: Display service configuration in a readable format.
  • docker swarm leave --force: Make a node leave the cluster; managers must include --force.

Best Practices

  • Run three or five manager nodes in production to ensure high availability through the Raft consensus protocol.
  • Set manager nodes to drain mode so they do not run application containers and can focus on cluster management.
  • Manage applications with Stack files to simplify version control and repeatable deployments.
  • Store sensitive data using docker secret instead of embedding it in images or environment variables.
  • Back up Swarm state regularly and monitor node health and resource consumption.

Conclusion

Docker Swarm is known for being simple, native, and easy to adopt. It provides an efficient path to container clustering for small and medium environments. Once the core concepts of nodes, services, tasks, and stacks are understood, teams can quickly move applications into production-grade cluster operations.