Un projet hérité sur deux, dans mes reprises, ne démarre nulle part ailleurs que sur sa production. La machine d’origine a disparu, le développeur aussi, et il reste un serveur vivant que personne n’ose redémarrer. C’est de là que je pars la plupart du temps.

J’arrive, je pose ma première question : « comment je le lance en local ? » Silence. Tant que la réponse manque, je ne peux rien tenter sans risquer de casser pour de vrai.

Reconstituer un environnement reproductible, c’est rassembler tout ce qu’il faut pour relancer un projet hérité à l’identique : versions, dépendances, configuration, services annexes. Idéalement dans un conteneur, pour que n’importe qui le redémarre sans la machine d’origine. C’est par là que je commence une reprise.

Pourquoi c’est bloquant

Sans environnement séparé, comprendre le code revient à bidouiller la production. La moindre erreur passe sous les yeux des utilisateurs, et certaines ne se rattrapent pas. On ne peut ni casser pour voir, ni vérifier une correction avant de l’envoyer. Résultat, le projet se fige par prudence, et la dette grossit pendant que tout le monde retient son souffle.

Les quatre familles à retrouver

Un environnement, c’est tout ce dont le code a besoin pour tourner. J’en cherche quatre choses :

  • les versions exactes du langage et des outils. Un projet calé sur Node 14 ne démarre pas sous Node 20, et le message d’erreur ne vous le dira pas franchement ;
  • les dépendances, avec leurs versions figées ;
  • les services annexes : base de données, cache, file de messages ;
  • la configuration, c’est-à-dire variables, connexions et secrets, que je remplace par des valeurs de test.

Sur un projet sans documentation, rien de tout ça n’est écrit. On le découvre à l’enquête. Le projet plante au démarrage, le message livre une pièce du puzzle, on la pose, ça plante un cran plus loin. J’ai passé trois jours une fois sur une appli PHP d’un client industriel : le code attendait une extension compilée à la main, mentionnée nulle part, repérée seulement parce qu’un require échouait au fond d’un fichier que plus personne n’ouvrait.

Le conteneur fige tout

L’idéal, c’est d’enfermer cet environnement dans une définition conteneurisée. Vous y gagnez la reproductibilité, d’abord : n’importe qui le relance pareil, sur sa machine, sans rituel. Et le fichier de définition tient lieu de documentation, une documentation qui s’exécute et se périme donc bien moins vite qu’un texte que plus personne ne relit.

Pour un projet hérité, c’est souvent la première fois que l’environnement existe ailleurs que dans la tête d’un absent. Ça règle au passage le fameux « ça marche chez moi » qui avait peut-être contribué au blocage initial.

Ce que ça débloque

Dès que le projet démarre dans un environnement reproductible et séparé, tout s’ouvre. Vous lisez le code en l’exécutant, des points d’arrêt posés où vous voulez. Une modification qui casse ? Vous repartez de zéro sans conséquence. On quitte le « je n’ose pas y toucher » pour entrer dans l’exploration tranquille. C’est rarement la partie la plus visible d’une reprise, et pourtant celle qui conditionne presque tout le reste.

Ca marche sur ma machine, mais la machine de l'absent est introuvable.

Là où la méthode trouve sa limite

Je ne prétends pas reconstituer à l’identique. Un environnement reproductible n’est jamais une copie parfaite de la production : il y manque la charge réelle, les volumes de données accumulés sur des années, les petits accidents de configuration qui font qu’un bug ne se reproduit que là-bas. Certains défauts ne se révèlent que sur la machine d’origine, et aucune reconstitution ne les fera apparaître chez moi. Ce que je livre est un point d’appui fiable pour travailler, pas un double exact du système vivant. Le confondre avec l’original mène à de mauvaises surprises au moment de remettre en production.

À lire aussi