Docker swarm guide
Skill WhiteMuush/Your-Claude-DevOps-Teacher/skills/docker-swarm-guide
My own configuration CLAUDE, Dev & Ops specialist and 100% educational.
npx -y skills add WhiteMuush/Your-Claude-DevOps-Teacher --skill docker-swarm-guideAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Orchestration avec Docker Swarm incluant services, stacks, overlay networks, secrets, rolling updates et haute disponibilité. Se déclenche avec "Docker Swarm", "swarm mode", "docker service", "docker stack", "overlay network"
SKILL.md
8.6 KB, as published. Nobody here has run it
Docker Swarm Guide
Critères de choix : Swarm vs Kubernetes
| Critère | Swarm | Kubernetes |
|---|---|---|
| Équipe < 5 devops | ✅ | ❌ complexité op |
| Infra on-premise simple | ✅ | possible mais lourd |
| Multitenancy avancé | ❌ | ✅ |
| RBAC fin, CRDs, Operators | ❌ | ✅ |
| Stack existante Docker Compose | ✅ migration facile | conversion nécessaire |
Choisis Swarm si tu as déjà des Compose files, une petite équipe, et pas besoin de scaling horizontal à 100+ nœuds.
Workflow en étapes
1. Initialiser le cluster
# Sur le premier manager (remplace l'IP par l'IP privée réseau inter-nœuds)
docker swarm init --advertise-addr 192.168.1.10
# Récupérer les tokens
docker swarm join-token manager # pour ajouter un manager
docker swarm join-token worker # pour ajouter un worker
# Rejoindre depuis un autre nœud
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377
# Vérifier l'état du cluster
docker node ls
Règle de quorum Raft : toujours un nombre impair de managers.
- 3 managers → tolère 1 panne
- 5 managers → tolère 2 pannes
- Ne jamais dépasser 7 managers (latence consensus)
# Promouvoir un worker en manager
docker node promote <node-id>
# Vérifier la santé du Raft
docker node inspect self --format '{{ .ManagerStatus.Reachability }}'
2. Configurer les overlay networks
# Réseau chiffré pour données sensibles
docker network create \
--driver overlay \
--opt encrypted \
--subnet 10.0.1.0/24 \
backend-net
# Réseau frontend non chiffré (moins de CPU)
docker network create --driver overlay frontend-net
Pattern d'isolation recommandé :
frontend-net: load balancer ↔ appbackend-net: app ↔ base de donnéesmonitoring-net: agents de monitoring (attachable)
# Réseau attachable pour debug/tests ad hoc
docker network create --driver overlay --attachable debug-net
3. Déployer un service
# Service minimal avec réplicas
docker service create \
--name api \
--replicas 3 \
--network backend-net \
--publish published=8080,target=3000 \
--limit-cpu 0.5 \
--limit-memory 256M \
--reserve-cpu 0.25 \
--reserve-memory 128M \
--health-cmd "curl -f http://localhost:3000/health || exit 1" \
--health-interval 10s \
--health-retries 3 \
myrepo/api:1.2.0
# Inspecter les tasks et leur état
docker service ps api --no-trunc
Contraintes de placement :
# Forcer sur nœuds labellisés SSD
docker node update --label-add disk=ssd worker-1
docker service create \
--constraint 'node.labels.disk == ssd' \
--name db \
postgres:16
4. Stacks avec docker-compose (méthode recommandée)
# docker-compose.prod.yml
version: "3.9"
services:
api:
image: myrepo/api:${API_VERSION:-latest}
networks:
- frontend-net
- backend-net
secrets:
- db_password
environment:
DB_HOST: db
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 15s
failure_action: rollback
monitor: 30s
order: start-first # zero-downtime : nouveau container avant l'arrêt
rollback_config:
parallelism: 1
delay: 10s
failure_action: pause
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: "0.5"
memory: 256M
reservations:
cpus: "0.25"
memory: 128M
placement:
constraints:
- node.role == worker
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 20s
db:
image: postgres:16
networks:
- backend-net
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- db-data:/var/lib/postgresql/data
deploy:
replicas: 1
placement:
constraints:
- node.labels.disk == ssd
networks:
frontend-net:
driver: overlay
backend-net:
driver: overlay
driver_opts:
encrypted: "true"
volumes:
db-data:
secrets:
db_password:
external: true
# Déployer / mettre à jour la stack
docker stack deploy -c docker-compose.prod.yml myapp
# Lister les services de la stack
docker stack services myapp
# Retirer la stack (ne supprime pas les volumes)
docker stack rm myapp
5. Gérer secrets et configs
# Créer un secret depuis stdin (jamais depuis un fichier en clair en prod)
echo "S3cr3tP@ss" | docker secret create db_password -
# Depuis un fichier
docker secret create tls_cert ./cert.pem
# Lister / inspecter (le contenu n'est jamais affiché)
docker secret ls
docker secret inspect db_password
# Config (non sensible, fichiers de conf, templates)
docker config create nginx_conf ./nginx.conf
# Usage dans un service
docker service update \
--config-add source=nginx_conf,target=/etc/nginx/nginx.conf \
nginx
Les secrets sont montés en RAM (tmpfs) dans /run/secrets/<nom>. Ils ne touchent jamais le disque du worker.
6. Rolling updates et rollbacks
# Mise à jour de l'image (zero-downtime avec order: start-first)
docker service update \
--image myrepo/api:1.3.0 \
--update-parallelism 1 \
--update-delay 15s \
--update-failure-action rollback \
api
# Suivre la progression
docker service ps api --filter desired-state=running
# Rollback manuel immédiat
docker service rollback api
# Forcer un redémarrage sans changer l'image (ex. secrets modifiés)
docker service update --force api
7. Services globaux et monitoring
# Déployer un agent Prometheus Node Exporter sur CHAQUE nœud
docker service create \
--name node-exporter \
--mode global \
--network monitoring-net \
--mount type=bind,src=/proc,dst=/host/proc,ro=true \
--mount type=bind,src=/sys,dst=/host/sys,ro=true \
prom/node-exporter:latest
Garde-fous et anti-patterns
❌ Ne jamais faire
# DANGER : expose les secrets dans docker inspect / logs
docker service create -e DB_PASSWORD=secret123 myapp
# DANGER : manager utilisé comme worker en prod
# (le manager gère le Raft, surcharge CPU = instabilité quorum)
docker node update --availability drain manager-1 # ← correct pour drainer
# DANGER : volume local partagé entre réplicas sans NFS/Ceph
# Chaque réplica sur son nœud a sa propre copie locale → incohérence
⚠️ Pièges courants
| Piège | Symptôme | Solution |
|---|---|---|
update_config.order: stop-first (défaut) | Downtime pendant update | Passer à start-first |
Pas de healthcheck | Tasks "Running" mais app down | Toujours définir un healthcheck |
Pas de resource limits | Un service OOM tue le nœud | Toujours limiter CPU + RAM |
| Quorum perdu (2 managers sur 3 HS) | Cluster en read-only | Restaurer via docker swarm init --force-new-cluster |
Image latest en prod | Rollback impossible | Toujours tagger les versions |
| Drain d'un nœud sans vérifier les réplicas | Réplicas reschedulés sur nœuds surchargés | Surveiller docker service ps après drain |
Commandes de diagnostic
# État global du cluster
docker node ls
docker service ls
# Tasks en échec
docker service ps <service> --filter desired-state=shutdown
# Logs d'un service (toutes les tasks)
docker service logs --follow --tail 100 api
# Inspecter un nœud (labels, ressources)
docker node inspect <node-id> --pretty
# Stats CPU/mémoire des containers sur le nœud local
docker stats --no-stream
Bonnes pratiques 2026
- Registre privé avec TLS : configurer
--with-registry-authsurdocker stack deploypour que le swarm puisse puller depuis un registre privé. - Rotation des secrets : créer un nouveau secret versionné (
db_password_v2), mettre à jour le service, puis supprimer l'ancien, le Swarm ne supporte pas la mise à jour in-place d'un secret. - Drain avant maintenance :
docker node update --availability drain <node>migre proprement les tasks avant de toucher au nœud. - Labels structurés : utiliser des labels hiérarchiques (
zone=eu-west,disk=ssd,gpu=true) pour des contraintes de placement précises. - CI/CD : coupler
docker stack deployà un pipeline GitLab/GitHub Actions avec le tag de commit comme version d'image, jamais delatesten production.