Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Deploy Docker Swarm Stacks

Deploy Docker stacks with Swarm mode. This lesson teaches how to use Docker Swarm to deploy multi-service applications as stacks, including practical exercises and next-step guidance.

Focus: deploy docker stacks with swarm mode

Sponsored

So you've mastered Docker Compose for local development, but when you try to run those same services in production, things fall apart — scaling bottlenecks, single-node failures, and no built-in rolling updates. Simply running docker-compose up on a server leaves you with a fragile, manually-managed setup. You need a way to declaratively define your entire multi-service application and deploy it onto a resilient cluster that handles failures and scaling automatically. This is exactly what Docker Swarm stacks provide: a production-grade, native orchestration layer that treats your Compose file as a deployment blueprint.

The problem this lesson solves

Running containers on a single Docker host is fine for prototyping, but it creates a single point of failure. If that machine goes down, your application goes with it. Even if you cluster multiple hosts manually, you're left orchestrating network overlay, load balancing, and service discovery by hand — a fragile, error-prone nightmare. Docker Swarm mode solves this by turning a pool of Docker hosts into a single, logical cluster with built-in high availability, load balancing, and declarative scaling. The "stack" concept takes your existing docker-compose.yml (with minor adjustments) and deploys it across the entire Swarm, managing the full lifecycle of your multi-service application.

Core concept / mental model

Think of a Docker Swarm stack as the production version of a Compose project. You write your application definition in a Compose file (YAML), then submit it to the Swarm manager. The manager interprets that file as a stack — it creates and manages all necessary services, networks, and volumes across the cluster.

  • Service: A declarative definition of a container's image, replicas, ports, environment variables, and update strategy. The Swarm scheduler ensures the desired number of replicas are running on healthy nodes.
  • Stack: A collection of related services that form a complete application. It groups them under one logical name and manages them as a unit.
  • Swarm: The underlying cluster of Docker hosts (manager + worker nodes) that provides the orchestration engine.

Pro tip: If you understand docker-compose.yml, you're 90% of the way to understanding a Swarm stack. The key differences are: you remove version (Swarm uses the Compose v3 schema), add deploy: keys for scaling and update config, and you use docker stack deploy instead of docker compose up.

How it works step by step

  1. Initialize the Swarm — On the manager node, run docker swarm init. This creates the control plane and generates a manager token.
  2. Join worker nodes — On each worker node, run docker swarm join --token <token> <manager-ip>:2377. This registers the worker in the cluster.
  3. Write your stack file — Create a Compose file (e.g., stack.yml) that defines your services, networks, and volumes. Add deploy: sections to control scaling, restart policy, and update behavior.
  4. Deploy the stack — From the manager node, execute docker stack deploy -c stack.yml <stack_name>. The manager analyzes the file and creates all resources.
  5. Verify and manage — Use docker stack services <stack_name> to list running services, docker stack ps <stack_name> to see individual tasks (replicas), and docker service scale <service_name>=<count> to adjust replicas.
  6. Update the stack — Modify your stack file, then run docker stack deploy -c stack.yml <stack_name> again. Swarm performs a rolling update based on the update_config in your deploy block.

The cause-and-effect chain is: your static YAML file → Swarm manager interprets it → creates/updates services → scheduler places tasks (containers) on available nodes → built-in load balancer (routing mesh) distributes traffic to healthy replicas.

Hands-on walkthrough

Let's build a real stack. You'll create a simple web app with a Python web server and a Redis cache, deployed across your local Swarm (simulating a cluster with multiple nodes locally).

Step 1: Initialize a single-node Swarm (for testing)

docker swarm init

Expected output:

Swarm initialized: current node (xxxx) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-... <IP>:2377

Step 2: Create stack.yml

Save this as stack.yml:

services:
  web:
    image: python:3.11-slim
    command: python -m http.server 80
    ports:
      - target: 80
        published: 8080
        protocol: tcp
        mode: ingress
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - frontend

  cache:
    image: redis:7-alpine
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
    networks:
      - backend

networks:
  frontend:
    driver: overlay
  backend:
    driver: overlay

Step 3: Deploy the stack

docker stack deploy -c stack.yml myapp

Expected output:

Creating network myapp_frontend
Creating network myapp_backend
Creating service myapp_web
Creating service myapp_cache

Step 4: Verify the deployment

docker stack services myapp
docker stack ps myapp

The first command shows each service with its replicas. The second shows the individual container tasks and which node they're running on.

Step 5: Test scaling and updates

Scaling the web service on the fly (without modifying the file):

docker service scale myapp_web=5

Then update the image (simulate a new version):

# Modify stack.yml to use 'python:3.12-slim', then redeploy
docker stack deploy -c stack.yml myapp

Watch the rolling update:

docker service ps myapp_web

You'll see tasks gradually replaced, respecting the parallelism and delay you defined in update_config.

Compare options / when to choose what

Feature Docker Swarm Stacks Kubernetes (K8s) Plain Docker Compose
Setup complexity Simple (built into Docker Engine) Complex (needs control plane setup) Trivial (local)
Built-in load balancing Routing mesh (ingress) Services + Ingress controllers Port mapping only
Scaling docker service scale kubectl scale Manual (not designed for multi-node)
Rolling updates Supported via update_config Supported via Deployment strategy Not natively supported
Secret management Docker secrets (v1) Kubernetes secrets Not built-in
Best for Small to medium deployments, teams already using Docker Large-scale, complex orchestration needs Local dev & single-node testing

When to choose Swarm stacks: You want native Docker integration, minimal operational overhead, and a familiar Compose-like syntax for production. It's ideal for teams that don't need K8s' complexity but still need multi-node resilience.

When to choose something else: If you need advanced auto-scaling, service mesh, or heterogeneous container orchestration (e.g., mixed Linux/Windows, complex ingress), Kubernetes is more capable. If you're on a single node, plain Compose is simpler.

Troubleshooting & edge cases

  • "This node is not a swarm manager" — Run docker swarm init first. Workers cannot deploy stacks.
  • "could not find an available, non-overlapping IPv4 address pool" — Docker's overlay network address pool is exhausted. Reset with docker swarm leave --force, then docker swarm init --default-addr-pool 10.10.0.0/16.
  • "No such image" on worker nodes — The image must exist on every node (or be pullable from a registry). For private images, use docker login on each node or create a Docker registry service as part of your stack.
  • Port conflicts — The mode: ingress uses the published port on every node. If a service uses the same published port as an existing service, the stack deploy will fail. Use different ports or mode: host.
  • Network not created — If you manually remove a stack network, subsequent deploy fails silently. Leave the stack first with docker stack rm <stack_name>.

Pro tip: Use docker stack deploy --prune -c stack.yml myapp to automatically remove services or networks that are no longer in your compose file. This prevents orphaned resources.

What you learned & what's next

You now understand how to deploy Docker stacks with Swarm mode — from initializing a cluster, writing a stack file, deploying it, scaling services, and performing rolling updates. You've seen how stacks solve the production readiness gap by adding built-in high availability, load balancing, and declarative management on top of your familiar Compose workflow.

In the next lesson, you'll learn Docker Stack Configuration Management — how to use Docker configs and secrets to manage environment-specific configuration and sensitive data across your Swarm stacks, keeping your application secure and portable across environments.

Practice recap

Create a stack file with two services: a Python Flask app (3 replicas) and a PostgreSQL database (1 replica, with a placement constraint to run only on the manager node). Deploy it to a single-node Swarm, then simulate a failure by stopping one of the Flask containers — observe how the Swarm recreates it automatically. Finally, perform a rolling update by changing the Flask image tag and redeploying the stack.

Common mistakes

  • Forgetting to initialize the Swarm before deploying a stack — you'll get 'this node is not a swarm manager'.
  • Using docker-compose up inside a Swarm cluster instead of docker stack deploy — stack features like scaling and rolling updates won't work.
  • Not adding deploy: sections to your Compose file, then wondering why scaling via docker service scale has no effect on the original compose setup.
  • Assuming all images are available on every node — worker nodes fail if they can't pull the image (especially private images).

Variations

  1. Use docker stack deploy with YAML files that include Compose spec v3.8 (or later) for advanced features like secrets and configs.
  2. For production, combine your stack with Docker secrets (secrets: in YAML) to manage API keys and passwords securely.
  3. If you need hybrid workloads (Linux + Windows containers), Swarm supports mixed clusters, but each service must target its appropriate OS via placement: constraints.

Real-world use cases

  • Deploy a microservices e-commerce backend (cart, payment, inventory) into a production cluster with 3 replicas per service for high availability.
  • Run a CI/CD pipeline worker pool where each worker is a service that scales automatically based on queue depth (e.g., Jenkins agents on Swarm).
  • Host a WordPress site with separate services for web, database, and caching, all updated via rolling updates with zero downtime.

Key takeaways

  • A Swarm stack is the production equivalent of a Compose project — it deploys multi-service applications across a cluster.
  • You initialize the Swarm with docker swarm init, then deploy stacks with docker stack deploy -c stack.yml <name>.
  • Stacks support built-in rolling updates via update_config in your deploy block, enabling zero-downtime deployments.
  • The routing mesh (ingress mode) automatically load balances traffic across all healthy replicas of a service.
  • Stacks are managed using docker stack, docker service, and docker node commands — not docker-compose.
  • For edge cases like exhausted IP pools or port conflicts, resetting the swarm or using host mode ports can help.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.