Module privé git NPM sur Heroku

J’essaie de déployer mon application sur Heroku, mais je compte sur l’utilisation de git repos en tant que modules. Je le fais pour la réutilisation du code entre les projets, par exemple, j’ai un enregistreur personnalisé que j’utilise dans plusieurs applications.

"logger":"git+ssh://git@bitbucket.org..............#master" 

Le problème est que Heroku n’a évidemment pas access à ssh à ce code. Je ne trouve rien sur ce problème. Idéalement, Heroku possède une clé publique que je peux simplement append aux modules.

Authentification de base

GitHub prend en charge l’authentification de base:

 "dependencies" : { "my-module" : "git+https://my_username:my_password@github.com/my_github_account/my_repo.git" } 

Comme le fait BitBucket:

 "dependencies" : { "my-module": "git+https://my_username:my_password@bitbucket.org/my_bitbucket_account/my_repo.git" } 

Mais avoir des mots de passe simples dans votre package.json n’est probablement pas souhaitable.

Jetons d’access personnels (GitHub)

Pour que cette réponse soit plus à jour, je vous suggère d’ utiliser un jeton d’access personnel sur GitHub au lieu du nom d’utilisateur / mot de passe.

Vous devriez maintenant utiliser:

 "dependencies" : { "my-module" : "git+https://:@github.com/my_github_account/my_repo.git" } 

Pour Github, vous pouvez générer un nouveau jeton ici:

https://github.com/settings/tokens

Mots de passe d’application (Bitbucket)

Les mots de passe des applications sont principalement conçus pour permettre la compatibilité avec les applications qui ne prennent pas en charge l’authentification à deux facteurs. Vous pouvez également les utiliser à cette fin. Tout d’abord, créez un mot de passe d’application , puis spécifiez votre dépendance comme ceci:

 "dependencies" : { "my-module": "git+https://:@bitbucket.org/my_bitbucket_account/my_repo.git" } 

Clé API [obsolète] pour les équipes (Bitbucket)

Pour BitBucket, vous pouvez générer une clé API sur la page Gérer l’équipe, puis utiliser cette URL:

 "dependencies" : { "my-module" : "git+https://:@bitbucket.org/team_name/repo_name.git" } 

Mise à jour 2016-03-26

La méthode décrite ne fonctionne plus si vous utilisez npm3, car npm3 récupère tous les modules décrits dans package.json avant d’exécuter le script de preinstall . Cela a été confirmé comme un bug .

Le buildpack officiel node.js Heroku inclut désormais heroku-prebuild et heroku-postbuild , qui seront exécutés avant et après l’ npm install . Vous devez utiliser ces scripts au lieu de preinstall et de postinstall dans tous les cas, pour prendre en charge à la fois npm2 et npm3.

En d’autres termes, votre package.json devrait ressembler à:

  "scripts": { "heroku-prebuild": "bash preinstall.sh", "heroku-postbuild": "bash postinstall.sh" } 

J’ai proposé une alternative à la réponse de Michael, en conservant l’exigence favorable (IMO) de garder vos informations d’identification hors du contrôle de la source, sans exiger de buildpack personnalisé. Cela a été causé par la frustration que le buildpack lié par Michael est plutôt obsolète.

La solution consiste à configurer et à supprimer l’environnement SSH dans les scripts preinstall et postinstall , plutôt que dans le buildpack.

Suivez ces instructions:

  • Créez deux scripts dans votre repo, appelons-les preinstall.sh et postinstall.sh .
  • Rendez-les exécutables ( chmod +x *.sh ).
  • Ajoutez ce qui suit à preinstall.sh :
  #!/bin/bash # Generates an SSH config file for connections if a config var exists. if [ "$GIT_SSH_KEY" != "" ]; then echo "Detected SSH key for git. Adding SSH config" >&1 echo "" >&1 # Ensure we have an ssh folder if [ ! -d ~/.ssh ]; then mkdir -p ~/.ssh chmod 700 ~/.ssh fi # Load the private key into a file. echo $GIT_SSH_KEY | base64 --decode > ~/.ssh/deploy_key # Change the permissions on the file to # be read-only for this user. chmod 400 ~/.ssh/deploy_key # Setup the ssh config file. echo -e "Host github.com\n"\ " IdentityFile ~/.ssh/deploy_key\n"\ " IdentitiesOnly yes\n"\ " UserKnownHostsFile=/dev/null\n"\ " SsortingctHostKeyChecking no"\ > ~/.ssh/config fi 
  • Ajoutez ce qui suit à postinstall.sh :
  #!/bin/bash if [ "$GIT_SSH_KEY" != "" ]; then echo "Cleaning up SSH config" >&1 echo "" >&1 # Now that npm has finished running, we shouldn't need the ssh key/config anymore. # Remove the files that we created. rm -f ~/.ssh/config rm -f ~/.ssh/deploy_key # Clear that sensitive key data from the environment export GIT_SSH_KEY=0 fi 
  • Ajoutez ce qui suit à votre package.json :

     "scripts": { "preinstall": "bash preinstall.sh", "postinstall": "bash postinstall.sh" } 
  • Générez une paire de clés privée / publique à l’aide de ssh-agent .

  • Ajoutez la clé publique en tant que clé de déploiement sur Github.
  • Créez une version codée en base64 de votre clé privée et définissez-la comme GIT_SSH_KEY configuration Heroku GIT_SSH_KEY .
  • Engagez et poussez votre application sur Github.

Lorsque Heroku construit votre application, avant que npm installe vos dépendances, le script preinstall.sh est exécuté. Cela crée un fichier de clé privée à partir du contenu décodé de la variable d’environnement GIT_SSH_KEY et crée un fichier de configuration SSH pour indiquer à SSH d’utiliser ce fichier lors de la connexion à github.com . (Si vous vous connectez à Bitbucket à la place, mettez à jour l’entrée Host dans preinstall.sh sur bitbucket.org ). npm installe ensuite les modules à l’aide de cette configuration SSH. Après l’installation, la clé privée est supprimée et la configuration est effacée.

Cela permet à Heroku de supprimer vos modules privés via SSH, tout en gardant la clé privée hors de la base de code. Si votre clé privée est compromise, comme il ne s’agit que de la moitié d’une clé de déploiement, vous pouvez révoquer la clé publique dans GitHub et régénérer la paire de clés.

En outre, comme les clés de déploiement GitHub disposent d’permissions en lecture / écriture, si vous hébergez le module dans une organisation GitHub, vous pouvez créer une équipe en lecture seule et lui affecter un utilisateur «à déployer». L’utilisateur de déploiement peut alors être configuré avec la moitié publique de la paire de clés. Cela ajoute une couche de sécurité supplémentaire à votre module.

C’est vraiment une mauvaise idée d’avoir des mots de passe en texte clair dans votre repository git, utiliser un jeton d’access est mieux, mais vous voudrez toujours être très prudent.

 "my_module": "git+https://ACCESS_TOKEN:x-oauth-basic@github.com/me/my_module.git" 

J’ai créé un buildpack nodeJS personnalisé qui vous permettra de spécifier une clé SSH enregistrée avec ssh-agent et utilisée par npm lors de la première installation des dynos. Il vous permet de spécifier votre module comme une URL ssh dans votre package.json comme indiqué:

 "private_module": "git+ssh://git@github.com:me/my_module.git" 

Pour configurer votre application pour utiliser votre clé privée:

  • Générer une clé: ssh-keygen -t rsa -C "your_email@example.com" (Ne pas entrer de phrase de passe. Le buildpack ne prend pas en charge les clés avec des mots de passe)
  • Ajoutez la clé publique à github: pbcopy < ~/.ssh/id_rsa.pub (sous OS X) et collez les résultats dans github admin
  • Ajoutez la clé privée à la configuration de votre application heroku: cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy , puis heroku config:set GIT_SSH_KEY= --app your-app-name
  • Configurez votre application pour utiliser le buildpack comme décrit dans le README du buildpack heroku nodeJS inclus dans le projet. En résumé, le moyen le plus simple est de définir une valeur de configuration spéciale avec heroku config: définie sur l'URL github du référentiel contenant le buildpack souhaité. Je recommande de forking ma version et de créer un lien vers votre propre fork de github, car je ne vous promets pas de ne pas changer mon buildpack.

Mon buildpack personnalisé peut être trouvé ici: https://github.com/thirdiron/heroku-buildpack-nodejs et cela fonctionne pour mon système. Les commentaires et les demandes de tirage sont les bienvenus.

Sur la base de la réponse de @fiznool, j’ai créé un buildpack pour résoudre ce problème en utilisant une clé ssh personnalisée stockée en tant que variable d’environnement. Comme le buildpack est indépendant de la technologie, il peut être utilisé pour télécharger des dépendances à l’aide de tout outil tel que compositeur pour php, bundler pour ruby, npm pour javascript, etc.: https://github.com/simon0191/custom-ssh-key-buildpack

  1. Ajoutez le buildpack à votre application:

     $ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack 
  2. Générer une nouvelle clé SSH sans phrase secrète (disons que vous l’avez nommée deploy_key)

  3. Ajoutez la clé publique à votre compte de référentiel privé. Par exemple:

  4. Encode la clé privée en tant que chaîne base64 et l’ajoute à la variable d’environnement CUSTOM_SSH_KEY de l’application heroku.

  5. Faites une liste séparée par des virgules des hôtes pour lesquels la clé ssh doit être utilisée et ajoutez-la en tant que variable d’environnement CUSTOM_SSH_KEY_HOSTS de l’application heroku.

     # MacOS $ heroku config:set CUSTOM_SSH_KEY=$(base64 --input ~/.ssh/deploy_key) CUSTOM_SSH_KEY_HOSTS=bitbucket.org,github.com # Ubuntu $ heroku config:set CUSTOM_SSH_KEY=$(base64 ~/.ssh/deploy_key) CUSTOM_SSH_KEY_HOSTS=bitbucket.org,github.com 
  6. Déployez votre application et profitez de 🙂

Cette réponse est bonne https://stackoverflow.com/a/29677091/6135922 , mais j’ai changé un peu le script de préinstallation. J’espère que cela aidera quelqu’un.

 #!/bin/bash # Generates an SSH config file for connections if a config var exists. echo "Preinstall" if [ "$GIT_SSH_KEY" != "" ]; then echo "Detected SSH key for git. Adding SSH config" >&1 echo "" >&1 # Ensure we have an ssh folder if [ ! -d ~/.ssh ]; then mkdir -p ~/.ssh chmod 700 ~/.ssh fi # Load the private key into a file. echo $GIT_SSH_KEY | base64 --decode > ~/.ssh/deploy_key # Change the permissions on the file to # be read-only for this user. chmod ow ~/ chmod 700 ~/.ssh chmod 600 ~/.ssh/deploy_key # Setup the ssh config file. echo -e "Host bitbucket.org\n"\ " IdentityFile ~/.ssh/deploy_key\n"\ " HostName bitbucket.org\n" \ " IdentitiesOnly yes\n"\ " UserKnownHostsFile=/dev/null\n"\ " SsortingctHostKeyChecking no"\ > ~/.ssh/config echo "eval `ssh-agent -s`" eval `ssh-agent -s` echo "ssh-add -l" ssh-add -l echo "ssh-add ~/.ssh/deploy_key" ssh-add ~/.ssh/deploy_key # uncomment to check that everything works just fine # ssh -v git@bitbucket.org fi 

J’ai pu configurer la résolution de référentiels privés Github dans Heroku build via des jetons d’access personnels.

  • Générer un jeton d’access Github ici: https://github.com/settings/tokens
  • Définir le jeton d’access en tant que var Heroku config: heroku config:set GITHUB_TOKEN= --app your-app-name ou via Heroku Dashboard
  • Ajoutez le script heroku-prebuild.sh :

     #!/bin/bash if [ "$GITHUB_TOKEN" != "" ]; then echo "Detected GITHUB_TOKEN. Setting git config to use the security token" >&1 git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf git@github.com: fi 
  • Ajoutez le script de pré-construction à package.json :

     "scripts": { "heroku-prebuild": "bash heroku-prebuild.sh" } 

Pour l’environnement local, nous pouvons également utiliser git config ... ou nous pouvons append le jeton d’access au fichier ~/.netrc :

 machine github.com login PASTE_GITHUB_USERNAME_HERE password PASTE_GITHUB_TOKEN_HERE 

et installer des repos privés github devrait fonctionner.

npm install OWNER/REPO --save apparaîtra dans package.json comme: "REPO": "github:OWNER/REPO"

et résoudre les repos privés dans la construction Heroku devrait également fonctionner. facultativement, vous pouvez configurer un script postbuild pour GITHUB_TOKEN le GITHUB_TOKEN .

Vous pouvez utiliser dans le repository privé package.json avec l’exemple d’authentification ci-dessous:

 https://usernamegit:passwordgit@github.com/reponame/web/tarball/branchname 

Je l’ai déjà fait avec des modules de github. Npm accepte actuellement le nom du package ou un lien vers un fichier tar.gz contenant le package.

Par exemple, si vous souhaitez utiliser express.js directement depuis Github (récupérer le lien via la section de téléchargement), vous pouvez faire:

 "dependencies" : { "express" : "https://github.com/visionmedia/express/tarball/2.5.9" } 

Vous devez donc trouver un moyen d’accéder à votre référentiel en tant que fichier tar.gz via http (s).

Bref, ce n’est pas possible. La meilleure solution à ce problème est d’utiliser le nouveau sous-arbre git . Au moment où ces lignes sont écrites, elles ne sont pas dans la source officielle de git et doivent donc être installées manuellement, mais elles seront incluses dans la v1.7.11. Pour le moment, il est disponible sur homebrew et apt-get. c’est alors un cas de faire

 git subtree add -P /node_modules/someprivatemodue git@github.......someprivatemodule {master|tag|commit} 

Cela élimine la taille du repository mais une mise à jour est facile en exécutant la commande ci-dessus avec gitsubtree pull.