The "https://repo.packagist.org/packages.json" file could not be downloaded : ce message, apparu simultanément sur une dizaine de sites en cours de déploiement, a suffi à interrompre net une campagne de mise à jour censée durer une heure. Packagist traversait un ralentissement temporaire, et chaque serveur du parc tentait, en parallèle, de récupérer les mêmes métadonnées de paquets auprès du même service distant.
Ce type d’incident ne dépend pas d’une erreur de configuration locale : il tient à la dépendance directe, et non redondée, d’un parc entier envers une seule source externe. La solution retenue n’a pas consisté à attendre le retour de Packagist, mais à héberger en interne un miroir des paquets réellement utilisés par les projets du parc.
Pourquoi un miroir plutôt qu’un simple cache local par serveur
Un cache Composer local, activé par défaut sur chaque machine, accélère les installations répétées d’un même paquet sur le même serveur. Il ne protège en revanche pas contre une panne de Packagist lors d’une première résolution de dépendances, ni contre le throttling appliqué par certains miroirs publics en cas de pic de requêtes provenant d’une même plage d’adresses IP — situation fréquente lorsque plusieurs serveurs d’un même hébergeur déclenchent leurs mises à jour au même horaire programmé.
Un miroir Composer interne, à l’inverse, joue le rôle de point de passage unique entre le parc et Packagist : il interroge la source distante une seule fois, conserve les métadonnées et les archives de paquets localement, puis les redistribue à tous les serveurs qui en ont besoin, même si Packagist redevient indisponible entre-temps.
Mise en place avec Satis, l’outil officiel du projet Composer

Satis, maintenu par l’équipe de Composer, génère un dépôt statique à partir d’une liste de paquets déclarés dans un fichier de configuration. Il ne remplace pas Packagist : il en devient un reflet partiel, limité aux dépendances réellement utilisées par les projets du parc.
{
"repositories": [
{ "type": "composer", "url": "https://packagist.org" }
],
"require": {
"composer/composer": "*",
"wordpress/wordpress": "*",
"wpackagist-plugin/*": "*"
},
"output-dir": "/var/www/miroir-composer/web"
}
La génération du miroir s’exécute ensuite via la commande fournie par l’outil :
php satis.phar build satis.json /var/www/miroir-composer/web
Ce dossier est ensuite servi par un bloc serveur Nginx dédié, accessible uniquement depuis le réseau privé reliant les machines du parc, sans exposition publique inutile.
Faire pointer les projets vers le miroir sans réécrire chaque composer.json
Plutôt que de modifier chaque fichier composer.json des dizaines de projets existants, la bascule s’est faite au niveau de la configuration globale de Composer sur chaque serveur, via une commande exécutée une seule fois par machine :
composer config -g repositories.miroir composer https://miroir-composer.interne
composer config -g repo.packagist.org false
Cette configuration globale prend le pas sur Packagist pour toutes les résolutions de dépendances lancées depuis le serveur, sans qu’aucun projet n’ait besoin d’être touché individuellement.
Tenir le miroir à jour sans le transformer en nouveau point de fragilité
Un miroir figé au jour de sa création deviendrait vite un obstacle plutôt qu’une protection : impossible d’installer une nouvelle version d’une extension si elle ne figure pas dans la liste. La régénération du miroir a donc été programmée par une tâche cron dédiée, indépendante des campagnes de déploiement du parc :
- Régénération nocturne complète, hors des horaires de déploiement.
- Ajout manuel d’un paquet au fichier
satis.jsondès qu’un projet en introduit un nouveau. - Conservation des anciennes archives de paquets, pour ne jamais casser une installation qui référence une version précise déjà figée dans un
composer.lock.
Un miroir de paquets n’a de valeur que s’il vieillit correctement. Un miroir jamais régénéré finit par bloquer plus de déploiements qu’il n’en sécurise.
Ce que ce miroir ne couvre pas
Cette mise en place concerne exclusivement les dépendances PHP gérées par Composer. La gestion des dépendances npm côté outillage front, qui pose des problèmes différents de registre et de verrouillage de versions, n’entre pas dans ce périmètre et suit une logique distincte.
Notre verdict
Depuis la mise en place du miroir, plus aucune requête sortante directe vers Packagist n’est nécessaire lors d’un déploiement courant : le compteur de trafic sortant vers le service distant est retombé à zéro en fonctionnement normal, la seule sollicitation externe restante étant la régénération nocturne du miroir lui-même. La campagne de mise à jour suivante, menée sur l’ensemble du parc, s’est déroulée sans le moindre message d’échec de téléchargement, y compris pendant un nouveau ralentissement de Packagist survenu quelques semaines plus tard.