Aller au contenu principal
fschmitt.io
0%
Retour au blog
Docker DevOps

Migration Docker d'un client luxe : de 12 serveurs à 3 nœuds

12 mars 2025 · 8 min de lecture

Quand un client du luxe parisien m'a contacté fin 2023, son infra tenait sur 12 serveurs bare-metal répartis chez deux hébergeurs. Chaque serveur avait sa propre config, ses propres scripts de déploiement, et ses propres surprises quand on le redémarrait après une mise à jour noyau.

Le brief était simple : « On veut que ça coûte moins cher et que ça ne tombe plus. » En sous-texte, il y avait aussi : « Et arrêtez de nous appeler à 3h du matin. »

L'état des lieux

12 machines physiques. 3 pour les bases de données (une par marque), 4 pour le front web, 2 pour le back-office, 1 pour le cache, 1 pour les mails, 1 pour « les trucs de Jean-Marc » (un Elasticsearch que plus personne n'osait toucher).

Chaque serveur était configuré à la main. Pas d'Ansible, pas de scripts de provisioning. Le déploiement se faisait en SSH avec un script Bash qui datait de 2017 et qui commençait par #!/bin/bash -e — sauf que le -e avait été commenté « temporairement » trois ans plus tôt.

Le monitoring ? Un cron qui envoyait un mail quand le disque était plein. Sauf que la boîte mail de destination était elle aussi pleine.

La stratégie

L'objectif n'était pas de tout réécrire. C'était de passer d'un système fragile à un système reproductible, sans toucher au code applicatif. Le luxe a ses contraintes : zéro interruption visible, zéro risque sur les données clients.

J'ai découpé le plan en trois phases :

  • Phase 1 — Conteneurisation : transformer chaque service en image Docker, avec des Dockerfile propres et un docker-compose de dev qui reproduit l'ensemble de la stack en local.
  • Phase 2 — Infrastructure : 3 nœuds Proxmox en cluster, avec stockage Ceph répliqué et réseau VXLAN pour l'isolation des services.
  • Phase 3 — Migration live : bascule progressive, service par service, avec validation à chaque étape. Le front web en premier (le plus facile à rollback), les bases en dernier.

Les vrais problèmes

Sur le papier, ça avait l'air propre. En pratique, le premier problème est arrivé au bout de 48h : l'application PHP écrivait des fichiers temporaires dans /var/www/tmp/ avec des chemins absolus codés en dur dans 140 fichiers. Dans un conteneur éphémère, ces fichiers disparaissaient à chaque redémarrage.

La solution : un volume persistant monté sur /var/www/tmp, avec un job cron dans le conteneur qui purge les fichiers de plus de 24h. Pas sexy, mais fonctionnel et compatible avec le code existant.

Deuxième problème : les sessions PHP. Trois frontaux, pas de partage de sessions. Les utilisateurs se retrouvaient déconnectés aléatoirement selon le front qui répondait. J'ai basculé les sessions sur Redis — un conteneur dédié, 128 Mo de RAM, problème réglé en une demi-journée.

Troisième problème, le plus vicieux : les bases de données. Le client avait des procédures stockées qui utilisaient des fonctionnalités spécifiques à la version exacte de MySQL 5.7.38. Le passage à MariaDB 10.11 a cassé deux requêtes sur des jointures latérales non standard. Il a fallu réécrire ces requêtes en collaborant avec leur développeur — sans casser la rétro-compatibilité avec le BO existant.

Les résultats

Après 6 semaines de travail (dont 2 de tests de charge avec K6) :

  • 12 serveurs → 3 nœuds : réduction de 60% de la facture hébergement
  • Temps de déploiement : de 45 minutes (avec sueur froide) à 3 minutes (avec GitLab CI/CD)
  • Uptime : pas une seule interruption non planifiée en 14 mois
  • Temps de restauration : de « on espère que la sauvegarde fonctionne » à 12 minutes chrono

Ce que j'en retiens

La containerisation n'est pas un objectif en soi. C'est un moyen de rendre une infrastructure reproductible. Le vrai gain n'est pas technique — c'est la tranquillité d'esprit. Quand un nœud tombe, le service continue. Quand il faut scaler pour un lancement produit, on ajoute un conteneur. Quand un nouveau développeur arrive, il lance docker compose up et il a l'environnement complet en 5 minutes.

Et surtout : plus personne ne m'appelle à 3h du matin.