Pages

vendredi 1 août 2014

NodeJS comment créer un dépôt privé et monter un cache de npmjs.org

Personnellement je ne suis pas un fan de NodeJs. Mais je reste admiratif de tout l’écosystème qui s’est développé autour,  notamment autour de son gestionnaire de paquet npm. Npm permet de charger un module, de gérer ses dépendances vers d’autres, de gérer les évolutions de versions.


Les dépendances des paquets Node
Aujourd’hui le site npm enregistre 15 millions de téléchargements de paquets par jour. Ce nombre ne représente pas 15 millions de personnes car quand vous téléchargez un paquet, les dépendances sous-jacentes peuvent et sont souvent assez importantes.

Prenons un exemple simple avec Bower  (les dépendances sont exposées dans le fichier package.json à la racine du projet node).

    "abbrev": "~1.0.4",
    "archy": "0.0.2",
    "bower-config": "~0.5.0",
    "bower-endpoint-parser": "~0.2.0",
    "bower-json": "~0.4.0",
    "bower-logger": "~0.2.1",
    "bower-registry-client": "~0.1.4",
    "cardinal": "~0.4.0",
    "chalk": "~0.2.0",
    "chmodr": "~0.1.0",
    "decompress-zip": "~0.0.3",
    "fstream": "~0.1.22",
    "fstream-ignore": "~0.0.6",
    "glob": "~3.2.1",
    "graceful-fs": "~2.0.0",
    "handlebars": "~1.0.11",
    "inquirer": "~0.3.0",
    "junk": "~0.2.0",
    "mkdirp": "~0.3.5",
    "mout": "~0.7.0",
    "nopt": "~2.1.1",
    "lru-cache": "~2.3.0",
    "open": "~0.0.3",
    "osenv": "0.0.3",
    "promptly": "~0.2.0",
    "q": "~0.9.2",
    "request": "~2.27.0",
    "request-progress": "~0.3.0",
    "retry": "~0.6.0",
    "rimraf": "~2.2.0",
    "semver": "~2.1.0",
    "stringify-object": "~0.1.4",
    "sudo-block": "~0.2.0",
    "tar": "~0.1.17",
    "tmp": "~0.0.20",
    "update-notifier": "~0.1.3",
    "which": "~1.0.5",
    "p-throttler": "~0.0.1"

Pour installer Bower, nous devons installer pas moins de 40 autres modules. Au delà du nombre nous avons aussi un problème de taille. Par exemple l’utilisation des paquets Yeoman (Yo, Bower et Grunt) demande 160Mo d’espace au niveau du dépôt partagé npm et, 150Mo en local sur chacun des projets.

Vous me direz l’espace disque ne coûte pas cher… Mais lorsque nous sommes en entreprise nous avons l’habitude de travailler à plusieurs sur les mêmes projets, d’avoir des builds automatisés sur plusieurs serveurs ayant des droits restreints pour accéder à Internet… Le site de npm peut également avoir des problèmes d’engorgement ou d’accessibilité.

Comment faire pour limiter les appels aux dépôts distants sur le web ? Comment faire pour partager en interne des packages Node sans les faire sortir de l’entreprise ?

Utiliser Sinopia
En Java, la problématique est la même avec les dépôts distants Maven qui contiennent les différentes librairies. Pour résoudre cette problématique nous utilisons un gestionnaire de dépôt privé comme Nexus ou Artifactory. Il est important de noter qu’Artifactory permet depuis sa version 3.2, de jouer le rôle de proxy et de dépôt privé de packages Javascript….

Mais cette solution est payante et nous allons voir comment résoudre ce problème en utilisant un module Node nommé sinopia. En théorie c’est super simple : vous devez lancer la commande
npm install -g sinopia


Sauf que sinopia utilise node-gyp qui a des dépendances vers Python, qui lui a besoin d’un compilateur C++... Sous Windows (le côté obscur de beaucoup d’entreprises…) c’est un peu la galère, mais on arrive à ses fins en installant Visual C++ Express. Toutes les démarches sont expliquées sur le github de node-gyp.

Configuration de Sinopia
Placez vous dans le répertoire de travail de synopia (par exemple D:\nodeJS\sinopia) et lancez la commande sinopia.

La première fois laissez sinopia créer son propre fichier de configuration config.yaml



Le fichier de configuration permet de paramétrer les dépôts distants npm, et d’autres éléments comme votre proxy HTTP si besoin. Nous allons changer la valeur par défaut

listen: localhost:4873


Coupez sinopia et modifiez le fichier de config pour spécifier l’alias de votre serveur (dans mon cas sinopia.javamind.com).
listen: sinopia.javamind.com:4873


Allez sur les postes ou les serveurs qui accéderont à sinopia et modifier le dépôt utilisé par défaut
npm set registry http://sinopia.javamind.com:4873

Et le tour est joué...

Exécution de Sinopia
Pour le moment Sinopia a été lancé dans une console de commande mais nous voulons que le proxy tourne en permanence. Dans mon cas je suis dans un environnement Windows donc je me suis rabattu sur un outil Open Source NSSM - the Non-Sucking Service Manager

Le principe est simple. Commencez par créer un script startup.bat qui contiendra :
cd D:\NodeJS\sinopia
call sinopia


Ensuite lancez nssm.exe en ligne de commande pour installer un nouveau service
nssm.exe install nodeSinopia

Une fenêtre s’ouvre pour vous aider à paramétrer votre service



Cliquez sur “Install Service” puis lancez la commande
nssm.exe start nodeSinopia

Vous pouvez changer la configuration du service en lançant la commande
nssm.exe edit nodeSinopia

Référence
Pour plus d’informations vous pouvez lire la page liée à sinopia sur npmjs.org
Et la doc lié au projet NSSM - the Non-Sucking Service Manager

merci à Agnes Crepet pour sa relecture

1 commentaire:

  1. Cet article tombe à point. Je cherchais justement à installer un repo node privé mais je n'avais pas trouvé. Thanks.

    RépondreSupprimer

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.