Docker Swarm — the lightweight K8s alternative
When 3-5 hosts need to coordinate but you don't want K8s, Swarm is the sweet spot. Init, join, rolling upgrades, monitoring.
Docker Swarm (3-10 nodes) 90 min
Why Swarm is still useful#
Docker downplays Swarm but still maintains it. Sweet spot:
- 3-10 hosts; you want load balancing + rolling upgrades + service discovery
- Team isn’t fluent in K8s
- Run docker-compose.yml directly (with a few deploy fields)
Init the cluster#
# First host (manager)
docker swarm init --advertise-addr <PUBLIC_IP>
# On other hosts:
docker swarm join --token <TOKEN> <MANAGER_IP>:2377
Deploy a stack#
Add deploy fields to your compose:
version: '3.8'
services:
chatwoot-rails:
image: chatwoot/chatwoot:v4.x
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
order: start-first
restart_policy:
condition: on-failure
networks: [ai-support]
secrets: [chatwoot_env]
postgres:
image: postgres:16
deploy:
placement:
constraints: [node.labels.role == db]
volumes:
- pg-data:/var/lib/postgresql/data
networks:
ai-support:
driver: overlay
secrets:
chatwoot_env:
external: true
Deploy:
docker stack deploy -c stack.yml ai-support
Concepts#
| Concept | Meaning |
|---|---|
| Service | A long-running container group |
| Replica | How many copies per service |
| Overlay network | Cluster-wide internal network |
| Secret | Encrypted sensitive value |
| Placement constraint | Pin a service to certain nodes |
Rolling upgrade#
docker service update --image chatwoot/chatwoot:v4.5.1 ai-support_chatwoot-rails
update_config.order: start-first brings up new versions before tearing down old — zero downtime.
Observability#
docker service ls
docker service ps ai-support_chatwoot-rails
docker service logs -f ai-support_chatwoot-rails
Layer Prometheus + cAdvisor + Grafana on top.
Swarm vs K8s#
| Situation | Pick |
|---|---|
| 3-10 hosts | Swarm |
| > 20 nodes / multi-team | K8s |
| Need Helm / Operator ecosystem | K8s |
| Docker-fluent, K8s-curious | Swarm |
| Heavy GitOps CI/CD | K8s (ArgoCD etc. are mature) |