Choosing Compose vs Swarm vs Kubernetes
Docker Compose, Docker Swarm, and Kubernetes all help you run more than one container, but they solve different sizes of problem. Compose is a simple single-host workflow, Swarm is Docker’s built-in cluster orchestrator, and Kubernetes is a large ecosystem for running applications across clusters. Choosing well matters because the wrong tool can make a small project heavy or a production system fragile.
Overview: How The Choices Work
Start with the Docker model underneath all three tools. An image is a read-only template made from stacked layers. A container is an instance of that image with a thin writable layer, runtime configuration, network attachments, mounts, and one main process. Orchestration does not replace images, layers, registries, or containers; it decides how many containers should exist, where they should run, how they communicate, and what should happen when something changes or fails.
Docker Compose reads a Compose file, usually compose.yml, and talks to one Docker Engine. It creates local networks, volumes, containers, and sometimes builds images for a project. It is excellent for development, tutorials, demos, CI integration tests, and simple single-server deployments. Compose has a desired shape for the project, but it is not a cluster control plane. If the one host dies, Compose cannot reschedule containers on another machine.
Docker Swarm is cluster orchestration built into Docker Engine. You initialize a swarm, join managers and workers, and create services with replica counts. Swarm stores desired state, schedules tasks on nodes, provides service discovery, can publish ports through routing mesh, and performs rolling updates. It feels familiar to Docker users because it uses docker service, docker stack, and Compose-like stack files. Its tradeoff is ecosystem size: it is simpler than Kubernetes, but fewer modern platforms, add-ons, and managed offerings center on Swarm.
Kubernetes is a separate orchestration platform with its own API objects: Pods, Deployments, Services, ConfigMaps, Secrets, Ingress, PersistentVolumeClaims, and more. Kubernetes is usually the default choice for organizations that need a rich production platform, managed cloud clusters, autoscaling, policy controls, service meshes, GitOps, custom controllers, or broad hiring familiarity. Its cost is operational complexity. A beginner can run a container quickly with Compose; a Kubernetes team must understand cluster upgrades, node pools, networking, storage classes, access control, observability, and YAML object relationships.
A useful rule: choose the smallest tool that honestly covers the failure modes you must handle. If you need repeatable local startup for a web app and database, use Compose. If you need a small Docker-native cluster and your team owns the machines, Swarm may be enough. If you need a standard production platform with many integrations and long-term scale, Kubernetes is usually the stronger bet.
Syntax
Compose uses a project file and a small set of lifecycle commands:
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
cache:
image: redis:7.4-alpine
docker compose up -d
docker compose ps
docker compose logs web
docker compose down
Swarm uses service commands or stack deployment:
docker swarm init
docker service create --name web --replicas 3 --publish 8080:80 nginx:1.27-alpine
docker service ls
docker service scale web=5
docker service rm web
docker swarm leave --force
Kubernetes usually uses manifest files applied to a cluster:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27-alpine
ports:
- containerPort: 80
| Need | Compose | Swarm | Kubernetes |
|---|---|---|---|
| Best fit | Local dev, demos, CI, one host | Small Docker-native clusters | Production platforms and large ecosystems |
| Scope | One Docker Engine | Multiple Docker Engine nodes | Cluster API across nodes |
| Main unit | Service creates containers | Service creates tasks | Deployment creates Pods |
| Learning curve | Low | Moderate | High |
| Failure recovery | Host-level only | Reschedules service tasks | Reschedules Pods with rich controllers |
| Ecosystem | Docker tooling | Docker tooling | Very large cloud-native ecosystem |
Examples
Example 1: Choose Compose For Local Development
A developer wants one command to run a web container and Redis. Compose is the right level because the app only needs repeatable local wiring.
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
depends_on:
- redis
redis:
image: redis:7.4-alpine
docker compose up -d
docker compose ps
Output:
[+] Running 3/3
- Network app_default Created
- Container app-redis-1 Started
- Container app-web-1 Started
NAME IMAGE SERVICE STATUS PORTS
app-web-1 nginx:1.27-alpine web Up 4 seconds 0.0.0.0:8080->80/tcp
app-redis-1 redis:7.4-alpine redis Up 4 seconds
Compose creates a private network where web can resolve redis by service name. It publishes only Nginx to the host. This is fast, understandable, and easy to delete with docker compose down.
Example 2: Choose Swarm For A Small Docker-Native Cluster
A team has a few Linux servers and wants replicated services without adopting the full Kubernetes model. Swarm can keep a service at the requested replica count.
docker swarm init
docker service create --name web --replicas 3 --publish 8080:80 nginx:1.27-alpine
docker service ls
Output:
Swarm initialized: current node is now a manager.
ID NAME MODE REPLICAS IMAGE
q8example web replicated 3/3 nginx:1.27-alpine
The service says, “keep three copies of this task running.” On one node they all run locally; on a real swarm, the scheduler can place tasks on workers. Swarm is still Docker underneath: each selected node pulls the image manifest and layers, creates containers, attaches networking, and starts the Nginx process.
Example 3: Choose Kubernetes For Platform Features
A company needs a standard deployment object that can be managed by cloud load balancers, autoscalers, policy tools, and GitOps workflows. Kubernetes is a better match even though the manifest is more verbose.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27-alpine
ports:
- containerPort: 80
kubectl apply -f deployment.yaml
kubectl get deployment web
Output:
deployment.apps/web created
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 20s
The Deployment controller creates ReplicaSets, which create Pods. Kubernetes watches actual state and reconciles it toward the declared state. In practice you would usually add a Service object for stable networking and maybe an Ingress object for external HTTP routing.
How It Works Step By Step
- You describe services with images, ports, environment variables, mounts, and replica counts.
- The tool records desired state. Compose stores enough local project state to manage one Docker Engine. Swarm stores cluster state with managers. Kubernetes stores objects in its API server and backing datastore.
- A scheduler or local engine compares desired state with actual state. Missing containers, tasks, or Pods are created.
- The selected node needs the image. It pulls the registry manifest and any missing read-only layers, then Docker or another container runtime prepares a writable layer for the container.
- Networking and storage are attached. Compose creates Docker networks and volumes. Swarm adds cluster service discovery and published ports. Kubernetes uses CNI networking and storage classes through its platform integrations.
- The container process starts. Health checks, exits, and node status flow back to the orchestrator.
- During updates, the orchestrator replaces old containers with new ones according to its rollout rules. Kubernetes and Swarm have stronger cluster rollout models than Compose.
Common Mistakes
Using Kubernetes Because It Sounds More Professional
Wrong for a simple local project:
kubectl apply -f development-only-app.yaml
If the real need is “start my app, database, and cache on my laptop,” Kubernetes adds concepts that do not solve the immediate problem. A Compose file is easier to read, faster to reset, and closer to the developer workflow.
Treating Compose Scaling As High Availability
Wrong expectation:
docker compose up -d --scale web=3
This creates three containers on the same Docker Engine. It can test whether your app handles multiple replicas, but it does not protect against host failure or create a production load balancer. Use Swarm, Kubernetes, or a managed platform when the app must survive losing a machine.
Scaling A Database Like A Stateless Web App
Wrong:
docker service create --name postgres --replicas 3 postgres:16-alpine
Three PostgreSQL containers do not automatically become one replicated database. Stateful systems need stable identity, durable storage, backups, replication configuration, and failure procedures. Often the best orchestrator choice is to run the app containers in Docker and use a managed database outside the cluster.
Deploying Moving Tags
Wrong:
docker service create --name web --replicas 3 nginx:latest
latest is only a tag name, not a guarantee of freshness or stability. Different nodes can pull different contents at different times. Prefer tested tags such as nginx:1.27-alpine, and for strict production reproducibility pin an image digest.
Best Practices
- Use Compose by default for local development, examples, CI smoke tests, and single-host stacks.
- Consider Swarm when you want Docker-native clustering, simple replicated services, and a smaller operational surface than Kubernetes.
- Choose Kubernetes when the organization needs managed cloud support, autoscaling, advanced ingress, policy, custom controllers, or a large ecosystem.
- Keep application containers stateless when you plan to scale replicas. Put durable data in named volumes, platform storage, external databases, or managed services.
- Pin image versions. Avoid
latestin Compose files, Swarm services, and Kubernetes manifests used by other people or automation. - Do not bake secrets into images with
ENVorRUN; image layers are retained. Use Compose env files for local placeholders and the orchestrator’s secret store for real deployments. - Plan networking explicitly.
EXPOSEdocuments a container port, but it does not publish traffic; use Composeports:, Swarm--publish, or KubernetesServiceandIngress. - Practice updates and rollbacks before production. The orchestrator is only useful if the team understands what it will replace, restart, and preserve.
Practice Exercises
- You are building a tutorial app with a web service and Redis for your laptop. Choose Compose, Swarm, or Kubernetes, and write down the reason in one sentence. Hint: no multi-host failure recovery is required.
- A small internal app must run three web replicas across two company-owned servers. Decide whether Swarm could be enough, and list two questions you would ask about storage and ingress before committing.
- A product team needs cloud autoscaling, HTTP ingress, separate staging and production namespaces, and policy controls. Identify the orchestrator you would choose and the Kubernetes objects likely needed beyond a Deployment.
Summary
- Compose, Swarm, and Kubernetes all run containers, but they target different operational scopes.
- Compose is the simplest answer for one Docker Engine and repeatable developer workflows.
- Swarm is Docker’s built-in cluster mode and can manage replicated services across Docker nodes.
- Kubernetes is the broad production platform choice when ecosystem, integrations, and cluster policy matter.
- The underlying container model remains the same: images provide read-only layers, containers add a writable layer and run processes.
- Choose based on failure recovery, team skill, networking, storage, rollout needs, and ecosystem requirements instead of popularity alone.
