Docs / Containers & Docker / Setting Up Docker Swarm for Container Orchestration

Setting Up Docker Swarm for Container Orchestration

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 412 views · 3 min read

Docker Swarm is Docker's built-in container orchestration that turns multiple Docker hosts into a single virtual host. It provides service discovery, load balancing, rolling updates, and secret management with minimal complexity compared to Kubernetes. This guide covers deploying a production Docker Swarm cluster.

Swarm Architecture

  • Manager nodes — handle cluster management, scheduling, and API requests
  • Worker nodes — run container workloads
  • Services — the desired state of containers (replicas, networks, volumes)

Initialize the Swarm

# On the first manager node
docker swarm init --advertise-addr 10.0.0.1

# Output includes join tokens for workers and managers
# To add a worker:
docker swarm join --token SWMTKN-1-abc123... 10.0.0.1:2377

# To add another manager:
docker swarm join-token manager
docker swarm join --token SWMTKN-1-xyz789... 10.0.0.1:2377

Deploying Services

# Create a service
docker service create --name web --replicas 3 --publish 80:80 nginx

# Scale a service
docker service scale web=5

# Update a service (rolling update)
docker service update --image nginx:1.27 --update-parallelism 1 --update-delay 30s web

# List services
docker service ls

# Inspect service tasks
docker service ps web

Docker Stack (Compose for Swarm)

# stack.yml
version: "3.8"
services:
  web:
    image: nginx:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      rollback_config:
        parallelism: 1
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
    ports:
      - "80:80"
    networks:
      - frontend

  api:
    image: myapp/api:latest
    deploy:
      replicas: 2
    secrets:
      - db_password
    networks:
      - frontend
      - backend

  db:
    image: postgres:16
    deploy:
      placement:
        constraints: [node.role == manager]
    volumes:
      - db_data:/var/lib/postgresql/data
    secrets:
      - db_password
    networks:
      - backend

networks:
  frontend:
  backend:
    internal: true

volumes:
  db_data:

secrets:
  db_password:
    external: true
# Deploy the stack
docker stack deploy -c stack.yml myapp

# List stacks
docker stack ls

# List stack services
docker stack services myapp

# Remove stack
docker stack rm myapp

Secrets Management

# Create a secret
echo "MyDBPassword123!" | docker secret create db_password -
docker secret create tls_cert /path/to/cert.pem

# List secrets
docker secret ls

# Use in service
docker service create --name api --secret db_password myapp/api
# Secret available at /run/secrets/db_password inside the container

Node Management

# List nodes
docker node ls

# Drain a node (for maintenance)
docker node update --availability drain node-name

# Bring back online
docker node update --availability active node-name

# Add labels for placement constraints
docker node update --label-add zone=us-east node-name

# Use labels in placement
deploy:
  placement:
    constraints: [node.labels.zone == us-east]

Monitoring

# Service logs
docker service logs -f web

# Visualizer (web dashboard)
docker service create --name viz --publish 8080:8080 \
    --constraint node.role==manager \
    --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
    dockersamples/visualizer

Best Practices

  • Use 3 or 5 manager nodes for high availability (odd numbers for quorum)
  • Keep managers as managers — run workloads on worker nodes only
  • Use Docker secrets instead of environment variables for sensitive data
  • Set resource limits on all services to prevent resource starvation
  • Use rolling updates with order: start-first for zero-downtime deployments
  • Drain nodes before maintenance to gracefully reschedule tasks

Was this article helpful?