Le conteneur en production : Migrer une application « Legacy » vers un cluster Docker Swarm ultra-léger

Pourquoi migrer une application « legacy » vers un cluster Docker Swarm ultra-léger (et pas Kubernetes)
/opt/scripts
L’objectif de cet article, c’est exactement ça : prendre une application « legacy » (au sens large, pas forcément vieille en techno, plutôt vieille en habitudes), la passer en conteneurs, et l’exploiter avec une orchestration simple. Sans sur-ingénierie, sans vous forcer à refaire toute l’architecture en même temps.
Et donc, pourquoi Docker Swarm et pas Kubernetes ?
Parce que dans énormément de contextes, Swarm est suffisant. Et quand je dis « suffisant », je parle de besoins concrets en production : haute dispo basique, rolling updates, réseau overlay, gestion de secrets, placement de services, et un modèle mental qui reste Docker. Vous n’ajoutez pas une nouvelle montagne de concepts tout de suite. La courbe d’apprentissage est faible, l’intégration est native, et surtout vous pouvez livrer plus vite.
Quand je dis « ultra-léger » ici, ça veut dire :
- 2 à 3 nœuds, pas 12.
- peu de dépendances autour, pas une plateforme entière.
- observabilité minimaliste mais utile.
- automatisation pragmatique, pas un framework de déploiement qui prend 3 mois.
Les résultats attendus, si vous faites ça proprement : des déploiements reproductibles, la capacité de rollback, une isolation nette (fini le serveur « snowflake »), une montée en charge modérée, et une sérénité opérationnelle qui change tout. Même si votre appli reste... héritage.
Ce que vous devez avoir avant de commencer (prérequis et garde-fous)
docker build
Listez les composants de la legacy :
- le binaire ou le code de l’application.
- le runtime (Java, .NET, Node, PHP-FPM, Python, etc.).
- Les Services Système utilisés (Systemd Units, Cron, Rsyslog).
- les fichiers de config et où ils vivent.
wkhtmltopdflibssl1.1- Les certificats, clés, chaines.
- Les répertoires « importants » (uploads, exports, caches, tmp).
Ensuite, identifiez les couples. C’est là que les migrations cassent.
Quelques classiques :
- état local non répliqué (uploads, fichiers générés).
/var/www/html/data- dépendance au hostname (licence, callbacks, auth).
- ports fixes, parfois en dur dans le code.
- accès direct à la base depuis l’app, sans timeouts, sans retry.
- jobs batch qui supposent « je suis sur la machine X ».
Stratégie de migration : conteneuriser d’abord, refactor ensuite. Vraiment. Faites un « lift-and-shift conteneurisé » pour stabiliser la livraison et l’exploitation. La modernisation viendra après, et elle sera plus facile, parce que vous aurez déjà supprimé le pire : l’unicité de la VM.
Côté environnements, cherchez la proximité : dev, staging, prod doivent utiliser les mêmes images. Les différences doivent passer par des variables, des configs et des secrets, pas par « sur prod on a installé un truc en plus ».
Check rapide avant de toucher à Swarm :
- versions Docker récentes et homogènes sur les nœuds.
- OS supporté et à jour (au moins patché).
- accès à un registry (interne ou externe).
- DNS interne fonctionnel.
- pare-feu : communication ouverte entre nœuds (ports Swarm), et entre services si besoin.
Architecture cible : un Swarm minimal mais « production-ready »
L’idée n’est pas de faire une maquette. On vise une petite architecture, mais exploitable.
Topologie recommandée
Deux options réalistes :
- 3 managers : meilleur compromis pour le quorum, plus robuste. C’est le « vrai » HA Swarm.
- 1 manager + 2 workers : plus simple, moins cher, mais le manager est un point sensible. Ça peut être acceptable si vous avez un plan de reprise (snapshot, reprovisionnement rapide) et que votre criticité est modérée.
Soyons directs : si vous pouvez vous permettre 3 machines, prenez 3 managers. Même petites. Même si votre charge applicative est faible.
Réseau
Swarm vous donne l’overlay network. En pratique, vous finissez souvent avec au moins deux réseaux :
- un réseau frontend pour ce qui est exposé (reverse proxy, app HTTP).
- un réseau backend pour DB, cache, workers, etc.
Pour les ports publiés, vous avez deux grands modes :
- ingress routing mesh : simple, vous publiez sur tous les nœuds, Swarm route vers les tasks.
- mode host : vous publiez sur le nœud où tourne la task. Utile pour latence, pour éviter certaines surprises réseau, ou pour des protocoles non HTTP. Mais ça demande plus de discipline sur le placement.
Registry et politique de tags
Ayez un registry. Docker Hub privé, GitLab Registry, Harbor, peu importe. Mais ayez une règle.
Une règle simple et efficace :
1.8.3)1.8.3-<sha><sha>)- idéalement, déployer en prod avec un tag immuable ou un digest.
latest
Sécurité de base
Swarm chiffre le trafic inter-nœuds, TLS est géré. Mais le reste, c’est vous.
- SSH durci, accès limité.
- mises à jour OS régulières.
- principe du moindre privilège dans les conteneurs.
- pas de secrets dans les images, ni dans le git.
Observabilité légère
Le piège, c’est de se dire « on verra plus tard ». Plus tard n’arrive jamais, et le jour où ça casse, vous êtes aveugle.
Version minimaliste acceptable :
- logs centralisés (Loki + Promtail, ou un ELK très réduit).
- métriques de base (node exporter, cAdvisor, un Prometheus simple).
- un Grafana léger.
Rien de luxueux. Juste de quoi diagnostiquer vite.
Étape 1 : conteneuriser la legacy sans la casser (Dockerfile pragmatique)
Le Dockerfile doit être ennuyeux. C’est un compliment.
Choisir une image de base stable
Debian slim ou Ubuntu slim, c’est souvent plus simple pour une legacy, parce que glibc est là, les libs aussi. Alpine est tentant, mais attention : musl vs glibc, binaires précompilés qui ne démarrent plus, libs manquantes, bugs subtils. Si vous n’êtes pas sûr, partez sur Debian slim. Vous optimiserez après.
Rendre la build reproductible
- pincez les versions (paquets, dépendances applicatives).
- utilisez le multi-stage build si vous compilez.
apt
Santé
HEALTHCHECK/health/ready
Utilisateur non root
/tmp/data/uploads
Tester localement
Avant Swarm, testez vraiment :
SIGTERM- ports.
- volumes montés.
- scénario « DB indisponible au boot ».
- redémarrage.
Si déjà localement c’est instable, en cluster ça sera juste plus instable, mais plus vite.
Étape 2 : remplacer docker-compose « local » par une stack Swarm (docker stack deploy)
docker-compose.yml
Différences clés compose vs Swarm
deploy
replicasplacementupdate_configrollback_configrestart_policylimitsreservations)
docker stack deploydocker compose up
Découper en services
Même si votre appli est un monolithe, essayez d’éviter le conteneur « tout-en-un » qui contient app + cron + worker + proxy.
Une découpe typique :
appworkerschedulerreverse-proxydb
Ça donne de la souplesse sur les replicas et les updates.
Politique de restart
restart_policy
condition: on-failureanymax_attemptswindow
Stratégie d’update et rollback
Swarm sait faire du rolling update. Utilisez-le.
parallelismdelaymonitorfailure_action: rollback
Structure de repo
Un truc simple :
/docker/stack/scripts/env
Étape 3 : routing et HTTPS : publier proprement en production
La façon la plus propre en Swarm, c’est de mettre un reverse proxy qui comprend le cluster.
Choisir un reverse proxy
Traefik est très adapté Swarm : découverte automatique via labels, gestion TLS, middlewares, métriques. Nginx ou HAProxy marchent aussi, mais vous devrez gérer plus de plomberie.
Traefik en Swarm
Le principe :
- Traefik tourne comme service (souvent en global sur les nœuds exposés, ou avec contraintes).
- vos services exposés ont des labels Traefik.
Les labels deviennent votre « contrat » de publication. Route, hostnames, TLS, middlewares.
Exposition des ports
80443- mode host : utile si vous voulez être sûr du chemin réseau, ou si vous faites du TCP spécifique.
Cas typique où host est utile : vous avez besoin d’IP client exacte sans ambiguïté, ou vous avez des contraintes de performance très strictes. Dans la plupart des cas web, ingress + Traefik suffit.
Headers et sécurité
Ajoutez des basiques :
- HSTS
X-Forwarded-For- limites de taille
- rate limiting basique si votre appli est fragile
Rien d’exotique. Juste ce que vous auriez dû avoir depuis longtemps.
Blue green simple
app_blueapp_green
Étape 4 : données et état : le vrai piège des migrations legacy
On peut conteneuriser presque n’importe quoi. Mais l’état, lui, se venge.
Cartographiez l’état :
- DB
- fichiers uploads
- cache
- queues
- sessions
Le principe à marteler : la base doit être durable et sauvegardée, et l’app doit pouvoir redémarrer n’importe où.
Sauvegardes
Ayez un plan de backup. Et surtout un plan de restore testé. Le backup non testé, c’est un talisman, pas une stratégie.
Choix typiques :
- dumps logiques (PostgreSQL, MySQL)
- snapshots disque (rapides, mais attention cohérence)
- réplication managée si possible
Migrations de schéma
replicas: 1
Permissions et UID GID
Si vous utilisez des volumes partagés, ou un stockage réseau, gardez des UID/GID cohérents entre nœuds. C’est un détail qui casse tout le reste. Et ça n’a rien à voir avec Swarm, c’est juste la réalité Linux.
Étape 5 : fiabilité : contraintes, limites et bonnes pratiques Swarm
Swarm est simple, mais il n’est pas magique.
Ressources
Mettez des limites CPU/RAM. Même approximatives. Sinon une fuite mémoire sur un worker peut tuer plusieurs services à la fois.
reservationslimits
Évitez l’oversubscription sauvage. Oui, ça « passe » jusqu’au jour où ça ne passe plus.
Placement
placement.constraints
- Traefik uniquement sur les nœuds exposés.
- services stateful sur des nœuds dédiés si vous en avez.
Et essayez d’avoir une forme d’anti-affinité, même simple, en répartissant les replicas. Swarm n’a pas toutes les subtilités de Kubernetes, mais vous pouvez déjà éviter d’avoir deux replicas sur le même nœud par accident.
Rolling update sans downtime
Le vrai secret, c’est la readiness. Un healthcheck qui passe, un reverse proxy qui attend, et un temps de grâce pour l’arrêt.
SIGTERM
Gestion des versions
- tags immuables
- idéalement digest pinning
- rollback basé sur une version connue, pas sur « on va rebuild vite »
Limites Swarm
Il faut le dire clairement :
- écosystème plus petit
- moins de features avancées (autoscaling fin, policy réseau complexe, CRDs, etc.)
Mais ça ne veut pas dire « pas production ». Ça veut dire « production simple ». Et pour une legacy, c’est souvent exactement ce qu’il faut.
Et si un jour vous avez besoin de plus, vous pourrez migrer. Swarm peut être une étape rentable, pas une impasse.
Étape 6 : pipeline de build et déploiement : passer du « SSH & scripts » à quelque chose de reproductible
Le grand gain des conteneurs, ce n’est pas juste l’isolation. C’est le pipeline.
Construisez une image à chaque commit via CI :
- cache de build
- scan de vulnérabilités (au moins un minimum)
- push vers registry
Publiez avec une politique claire :
latestversion+shastaging
Stratégie progressive :
- staging en premier
- puis prod avec approbation manuelle
- canary simple si possible (un replica sur N, ou un router Traefik dédié)
Secrets en CI :
- variables protégées
- injection via Swarm secrets
- rotation prévue (même si pas automatisée au début)
Traçabilité :
- stack file versionné
- notez la version déployée via labels (image, sha, date), même juste pour vous y retrouver à 2 h du matin.
Étape 7 : monitoring et logs (léger mais utile)
Ce qu’il faut absolument voir, sans débat :
- santé des services
- redémarrages
- saturation CPU/RAM
- erreurs 5xx et latence côté reverse proxy
- disque plein (le classique)
Logs
Tout en stdout/stderr. L’app doit parler là, pas dans un fichier perdu.
json-file
Option légère : Loki + Promtail. Ça se déploie bien en conteneurs, et ça évite un ELK trop lourd si vous n’en avez pas besoin.
Métriques
- node exporter sur les nœuds
- cAdvisor pour les conteneurs
- un Prometheus simple
- alertes sur seuils (redémarrages fréquents, mémoire, disque, load)
Traefik metrics et access logs : précieux. C’est souvent là que vous voyez les erreurs avant même que l’app ne vous le dise.
Tableau de bord
Grafana minimal. Objectif : diagnostiquer vite, pas « tout mesurer ». Les dashboards parfaits, c’est sympa, mais ce n’est pas ce qui évite une panne.
Plan de migration concret (timeline) : du POC à la prod sans coupure
Un plan réaliste, qui marche souvent.
Semaine 1 : audit + conteneurisation
- inventaire des composants
- Dockerfile pragmatique
- exécution locale
- tests de base (démarrage, arrêt, healthcheck)
- identification des volumes et secrets
Vous voulez un conteneur qui démarre de façon répétable. Même si ce n’est pas beau.
Semaine 2 : stack Swarm en staging
- création du Swarm (petit cluster)
- réseaux overlay
- Traefik (ou autre) et publication HTTPS
- secrets/configs gérés proprement
- tests d’intégration (app + DB + worker + cron)
docker stack deploy
Semaine 4 : déploiement progressif en prod
Oui, je laisse un trou. Parce qu’entre staging et prod, il y a la réalité. Corrections, ajustements, perf, et surtout données.
Stratégie safe :
- double run temporaire (ancienne VM continue, Swarm tourne en parallèle)
- synchronisation des données si nécessaire
- bascule progressive (DNS ou routing Traefik)
- rollback prêt, documenté, testé
Checklist go live :
- monitoring actif
- sauvegardes validées, restore testé
- runbook incident (même court)
- accès d’urgence (au cluster, au registry, aux logs)
Après prod :
- durcissement sécurité
- optimisation des images
- automatisation CI/CD
- réduction de dette technique, petit à petit, sans casser la prod
Conclusion : quand un Swarm ultra-léger est « le bon choix » pour une legacy
Le chemin, en vrai, est assez clair : conteneuriser, déployer en stack Swarm, publier proprement en HTTPS, gérer l’état sans tricher, fiabiliser avec des ressources et des updates, automatiser via CI, observer juste assez.
Le message clé, c’est que vous gagnez surtout en reproductibilité et en sérénité opérationnelle. Et ça, même si votre application reste une legacy. Même si le code n’est pas refactorisé. Même si vous n’avez pas « modernisé » au sens startup du terme.
Encadrons le choix : si vous avez besoin d’autoscaling très fin, de politiques réseau complexes, d’un gros écosystème d’opérateurs et d’extensions, Kubernetes finira peut-être sur la table. Plus tard. Mais Swarm peut être l’étape la plus rentable maintenant, celle qui enlève 80 % du risque en 20 % d’effort.
Si vous ne savez pas par où commencer, commencez par un POC. Une seule appli, une seule stack, un reverse proxy, des logs. Faites une checklist, itérez, et une fois que ça déploie proprement deux fois de suite, vous tenez quelque chose.
Questions fréquemment posées
Pourquoi choisir Docker Swarm plutôt que Kubernetes pour migrer une application legacy ?
Docker Swarm est souvent suffisant pour les besoins concrets en production comme la haute disponibilité basique, les mises à jour progressives (rolling updates), le réseau overlay, la gestion des secrets et le placement des services. Il offre un modèle mental simple, natif à Docker, avec une courbe d'apprentissage faible, permettant une livraison plus rapide sans sur-ingénierie.
Qu'entend-on par un cluster Docker Swarm "ultra-léger" ?
Un cluster Docker Swarm ultra-léger se compose généralement de 2 à 3 nœuds seulement, avec peu de dépendances externes, une observabilité minimaliste mais utile, et une automatisation pragmatique sans recours à un framework complexe. L'objectif est d'avoir une orchestration simple et efficace adaptée aux petites architectures.
Quels sont les prérequis avant de commencer la migration d'une application legacy vers Docker Swarm ?
Avant de commencer, il faut réaliser un inventaire honnête des composants de l'application (binaire, runtime, services système, fichiers de configuration, dépendances OS, certificats, répertoires importants). Il faut aussi identifier les couplages critiques comme l'état local non répliqué ou les chemins absolus codés en dur. Enfin, vérifier que les versions Docker sont récentes et homogènes, que le système d'exploitation est à jour, qu'un registry est accessible et que la communication réseau entre nœuds est ouverte.
Quelle stratégie adopter pour migrer une application legacy vers des conteneurs ?
La stratégie recommandée est de procéder d'abord à une conteneurisation « lift-and-shift », c’est-à-dire déplacer l’application telle quelle dans des conteneurs pour stabiliser la livraison et l’exploitation. La modernisation et le refactoring viendront ensuite plus facilement car l’unicité de la VM aura été supprimée.
Quelle architecture cible pour un cluster Docker Swarm en production ?
Deux topologies réalistes sont recommandées : soit 3 managers pour un quorum robuste assurant une haute disponibilité réelle du Swarm ; soit 1 manager avec 2 workers pour une solution plus simple et moins coûteuse mais avec un point sensible au niveau du manager. Si possible, il vaut mieux opter pour 3 machines managers même petites afin d'assurer la résilience du cluster.
Quels bénéfices attendus après migration vers Docker Swarm ?
Après migration propre vers Docker Swarm, on obtient des déploiements reproductibles avec capacité de rollback, une isolation nette évitant le serveur « snowflake », une montée en charge modérée possible et surtout une sérénité opérationnelle améliorée même si l’application reste legacy.
0 Commentaires