Aller au contenu
Développement medium

Nexus en cache : dépôt proxy PyPI, npm et Maven

10 min de lecture

Logo Nexus

Chaque build qui télécharge ses dépendances directement depuis PyPI, npm ou Maven Central paie deux fois : en latence et en fragilité (un paquet retiré ou un dépôt indisponible casse la CI). Un dépôt proxy Nexus règle les deux : il se place devant le dépôt public, met en cache ce qui transite, et sert les fois suivantes depuis le disque local. Ce guide crée un proxy PyPI, y branche pip, et prouve le pull-through cache. Public visé : débutant à intermédiaire. Validé sur Nexus 3.77.1.

  • Comprendre le fonctionnement d'un dépôt proxy (pull-through cache).
  • Créer un proxy PyPI, npm ou Maven.
  • Configurer un client pour passer par Nexus.
  • Vérifier qu'un paquet est bien mis en cache.
  • Une instance Nexus en marche, voir Installer Nexus.
  • Le mot de passe admin.

Un dépôt proxy est un miroir paresseux d'un dépôt distant. Il ne copie rien à l'avance : au premier téléchargement d'un paquet, Nexus le récupère en amont, le sert au client et en garde une copie. Les demandes suivantes sont servies depuis ce cache local, sans retoucher au dépôt public. C'est le pull-through cache.

Les bénéfices sont directs : builds plus rapides (le paquet est déjà là), résilience (une panne du dépôt amont n'empêche pas de servir ce qui est en cache) et maîtrise (vous voyez transiter tout ce que vos projets consomment).

Nexus crée déjà un pypi-public-proxy par défaut, mais voyons comment en déclarer un. Dans l'interface, Administration, Repositories, Create repository, puis pypi (proxy). Deux champs comptent : le nom et l'URL distante.

ChampValeur pour PyPI
Namepypi-public-proxy
Remote storagehttps://pypi.org

La même mécanique existe pour chaque format : https://registry.npmjs.org pour npm, https://repo1.maven.org/maven2/ pour Maven Central. On peut aussi créer un proxy par l'API, pratique pour scripter une installation :

Fenêtre de terminal
curl -u admin:VOTRE_MDP -X POST \
http://localhost:8081/service/rest/v1/repositories/pypi/proxy \
-H 'Content-Type: application/json' -d '{
"name": "pypi-public-proxy",
"online": true,
"storage": {"blobStoreName": "default", "strictContentTypeValidation": true},
"proxy": {"remoteUrl": "https://pypi.org", "contentMaxAge": 1440, "metadataMaxAge": 1440},
"negativeCache": {"enabled": true, "timeToLive": 1440},
"httpClient": {"blocked": false, "autoBlock": true}
}'

La page de configuration du dépôt reprend ces mêmes réglages dans l'interface :

Configuration d'un dépôt proxy PyPI dans Nexus : URL distante pypi.org et âge maximal des composants

Trois options gouvernent le comportement du cache :

  • Remote storage : l'URL du dépôt distant à mettre en cache (https://pypi.org). C'est le seul champ vraiment obligatoire.
  • Maximum component age : la durée (en minutes, 1440 = 24 h) pendant laquelle Nexus sert un artefact sans revérifier l'amont. Pour un dépôt de releases (immuables), on met -1 (jamais de revérification) ; pour des snapshots, une valeur courte.
  • Auto blocking : si l'amont devient injoignable, Nexus bloque automatiquement les appels sortants pour ne pas faire attendre les clients, et rétablit quand l'amont revient. C'est ce qui rend vos builds résilients à une panne de PyPI.

Côté client, on remplace l'URL du dépôt public par celle du proxy Nexus. Pour pip, on pointe l'index sur l'URL du dépôt Nexus :

~/.config/pip/pip.conf
[global]
index-url = http://localhost:8081/repository/pypi-public-proxy/simple/

Désormais, pip install <paquet> passe par Nexus, qui met en cache au passage. Pour npm, on ferait de même avec npm config set registry http://localhost:8081/repository/npm-public-proxy/.

C'est la vérification qui compte. On compte les composants en cache, on télécharge un paquet à travers le proxy, puis on recompte : le paquet doit apparaître.

  1. Compter les composants avant :

    Fenêtre de terminal
    curl -s -u admin:VOTRE_MDP \
    "http://localhost:8081/service/rest/v1/components?repository=pypi-public-proxy" \
    | jq '.items | length'
    6
  2. Télécharger un paquet à travers le proxy (ici le wheel de six) :

    Fenêtre de terminal
    curl -s -o /tmp/six.whl \
    "http://localhost:8081/repository/pypi-public-proxy/packages/six/1.16.0/six-1.16.0-py2.py3-none-any.whl"
  3. Recompter et vérifier que six est maintenant en cache :

    Fenêtre de terminal
    curl -s -u admin:VOTRE_MDP \
    "http://localhost:8081/service/rest/v1/components?repository=pypi-public-proxy" \
    | jq -r '.items | "nb: \(length)"'
    nb: 7

Le compteur passe de 6 à 7 et six 1.16.0 figure désormais dans le cache. Le second téléchargement du même paquet sera servi sans contacter PyPI : le pull-through cache est prouvé.

La vue Browse du dépôt proxy liste les paquets réellement mis en cache, dont six que l'on vient de télécharger, aux côtés de requests, urllib3 et leurs dépendances :

Vue Browse du dépôt pypi-public-proxy dans Nexus : les paquets mis en cache dont six

Agréger derrière une URL unique : le dépôt group

Section intitulée « Agréger derrière une URL unique : le dépôt group »

En pratique, on ne configure jamais un client directement sur un proxy. On crée un dépôt group qui réunit le proxy public et un dépôt hosted privé, et les clients pointent sur ce group. Nexus cherche alors d'abord dans le privé, puis dans le proxy, derrière une seule URL.

La configuration d'un group se résume à ordonner ses membres. Ici, le group pypi-all contient le hosted privé puis le proxy public :

Configuration d'un dépôt group PyPI dans Nexus : les membres hosted et proxy ordonnés

L'ordre compte : Nexus interroge les membres de haut en bas et renvoie la première correspondance. En plaçant le hosted privé en premier, une version interne masque une éventuelle homonyme publique, ce qui protège d'une attaque par confusion de dépendances. Côté client, on pointe simplement sur le group :

~/.config/pip/pip.conf
[global]
index-url = http://localhost:8081/repository/pypi-all/simple/

Un cache grossit sans fin si on ne l'élague pas, et en Community Edition il finit par heurter le quota de 40 000 composants. Les cleanup policies suppriment automatiquement les artefacts selon des critères : non téléchargés depuis X jours, plus vieux que Y, ou au-delà d'un nombre de versions à conserver.

On crée une politique dans Administration, Cleanup Policies. Ici, une règle purge les paquets PyPI non téléchargés depuis 30 jours :

Liste des cleanup policies dans Nexus : une règle de purge PyPI à 30 jours

SymptômeCause probableSolution
Le proxy renvoie 404 sur un paquetChemin de dépôt erronéVérifier l'URL /repository/<nom>/
Rien ne se met en cacheRequête sur l'index seulLe cache stocke les artefacts téléchargés, pas les pages d'index
Le proxy est « auto-blocked »Dépôt amont injoignableNexus le rebloque après une panne ; le débloquer une fois l'amont revenu
pip ignore NexusMauvais fichier de configVérifier index-url dans pip.conf
  • Un dépôt proxy met en cache un dépôt public au premier téléchargement (pull-through cache).
  • Il apporte vitesse, résilience (auto-blocking) et visibilité sur les dépendances consommées.
  • Le maximum component age règle la fréquence de revérification amont (-1 pour des releases immuables).
  • On expose un dépôt group (hosted avant proxy), pas le proxy directement : une seule URL et une protection contre la confusion de dépendances.
  • Les cleanup policies élaguent le cache pour maîtriser le stockage et rester sous le quota ; il faut les assigner à un dépôt.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn