Module git privé NPM sur Heroku
J'essaie de déployer mon application sur Heroku mais je compte sur l'utilisation de repos Git privés 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 accès ssh à ce code. Je ne trouve rien sur ce problème. Idéalement, Heroku a une clé publique que je peux simplement ajouter aux modules.
10 réponses
Auth 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"
}
Tout comme 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 souhaité.
Jetons D'accès personnels (GitHub)
Pour rendre cette réponse plus à jour, je suggère maintenant d'utiliser un jeton d'accès personnel sur GitHub au lieu de la combinaison nom d'utilisateur/mot de passe.
Vous devriez maintenant utiliser:
"dependencies" : {
"my-module" : "git+https://<username>:<token>@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 de L'application (Bitbucket)
Les mots de passe D'application sont principalement destinés à assurer la compatibilité avec les applications qui ne prennent pas en charge l'authentification à deux facteurs, et 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://<username>:<app-password>@bitbucket.org/my_bitbucket_account/my_repo.git"
}
[obsolète] clé API pour les équipes (Bitbucket)
Pour BitBucket, vous pouvez générer une clé API sur Manage Page de l'équipe, puis utilisez cette URL:
"dependencies" : {
"my-module" : "git+https://<teamname>:<api-key>@bitbucket.org/team_name/repo_name.git"
}
Mise à Jour 2016-03-26
La méthode décrite ne fonctionne plus si vous utilisez npm3, puisque npm3 récupère tous les modules décrits dans package.json
avant d'exécuter le script preinstall
. Ce a été confirmé comme un bug.
Le nœud officiel.js Heroku buildpack inclut désormais heroku-prebuild
et heroku-postbuild
, qui seront exécutés respectivement avant et après npm install
. Vous devez utiliser ces scripts au lieu de preinstall
et postinstall
dans tous les cas, pour prendre en charge à la fois npm2 et npm3.
Dans en d'autres termes, votre {[4] } devrait ressembler à:
"scripts": {
"heroku-prebuild": "bash preinstall.sh",
"heroku-postbuild": "bash postinstall.sh"
}
J'ai trouvé 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, tout en ne nécessitant pas un buildpack personnalisé. Cela a été confirmé par la frustration que le buildpack lié par Michael est plutôt obsolète.
La solution consiste à configurer et à détruire l'environnement SSH dans les scripts preinstall
et postinstall
de npm, au lieu de buildpack.
Suivez ces instructions:
- Créer deux scripts dans votre pension, appelons -
preinstall.sh
etpostinstall.sh
. - les rendre exécutables (
chmod +x *.sh
). - ajouter 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"\
" StrictHostKeyChecking no"\
> ~/.ssh/config
fi
- ajouter 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érer une paire de clés privée/publique en utilisant
ssh-agent
.- ajoute la clé publique en tant que clé de déploiement Github.
- créez une version codée en base64 de votre clé privée, et définissez-la comme Heroku config var
GIT_SSH_KEY
. - validez et poussez votre application sur Github.
Lorsque Heroku construit votre application, avant que npm n'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 au lieu de cela, mettez à jour l'entrée Host
dans preinstall.sh
vers bitbucket.org
). npm installe ensuite les modules en utilisant cette configuration SSH. Après l'installation, la clé privée est supprimée et la configuration est effacée.
Cela permet à Heroku d'extraire 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, puisqu'elle ne représente que 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 aparté, puisque Les clés de déploiement GitHub ont des autorisations de lecture/écriture, si vous hébergez le module dans une organisation GitHub, vous pouvez plutôt créer une équipe en lecture seule et lui attribuer un utilisateur 'deploy'. L'utilisateur deploy peut ensuite être configuré avec la moitié publique de la paire de touches. Cela ajoute une couche supplémentaire de sécurité à votre module.
C'est une très mauvaise idée d'avoir des mots de passe en texte brut dans votre repo git, utiliser un jeton d'accès est mieux, mais vous voudrez toujours être super prudent.
"my_module": "git+https://ACCESS_TOKEN:x-oauth-basic@github.com/me/my_module.git"
J'ai créé un pack de construction NodeJS personnalisé qui vous permettra de spécifier une clé SSH enregistrée avec ssh-agent et utilisée par npm lorsque les dynos sont configurés pour la première fois. Il vous permet de spécifier votre module en tant qu'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érez une clé:
ssh-keygen -t rsa -C "your_email@example.com"
(N'entrez aucune phrase secrète. 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 l'administrateur github - ajoutez la clé privée à la configuration de votre application heroku:
cat id_rsa | base64 | pbcopy
, puisheroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
- configurez votre application pour utiliser le buildpack comme décrit dans le fichier Heroku nodeJS buildpack README inclus dans le projet. En résumé, le plus simple est de définir une valeur de configuration spéciale avec Heroku config: définissez l'url github du référentiel contenant le buildpack souhaité. Je recommande de bifurquer ma version et de créer un lien vers votre propre fourche github, car je ne promets pas de ne pas changer mon buildpack.
Mon buildpack personnalisé peut être trouvé ici: https://github.com/thirdiron/heroku-buildpack-nodejs et ça marche 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 en utilisant n'importe quel outil comme composer pour php, bundler pour ruby, npm pour javascript, etc: https://github.com/simon0191/custom-ssh-key-buildpack
-
Ajoutez le buildpack à votre application:
$ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack
-
Générer une nouvelle clé SSH sans mot de passe (disons que vous l'avez nommé deploy_key)
-
Ajoutez la clé publique à votre compte de référentiel privé. Par exemple:
Encodez la clé privée en tant que chaîne base64 et ajoutez-la en tant que variable d'environnement
CUSTOM_SSH_KEY
de l'application heroku.-
Créez 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
- déployez votre application et profitez :)
Cette réponse est bonne https://stackoverflow.com/a/29677091/6135922 , mais j'ai changé un peu le script de préinstallation. Espérons 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 o-w ~/
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"\
" StrictHostKeyChecking 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 des dépôts privés Github dans Heroku build via des jetons D'accès personnels.
- générez le jeton d'accès Github ici: https://github.com/settings/tokens
- Définir jeton d'accès comme Heroku config var:
heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name
ou par Heroku tableau de bord -
Ajouter
heroku-prebuild.sh
script:#!/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
-
Ajouter le script préconstruit à
package.json
:"scripts": { "heroku-prebuild": "bash heroku-prebuild.sh" }
Pour l'environnement local, nous pouvons également utiliser git config ...
, ou nous pouvons ajouter l' jeton d'accès au fichier ~/.netrc
:
machine github.com
login PASTE_GITHUB_USERNAME_HERE
password PASTE_GITHUB_TOKEN_HERE
Et l'installation de repos GitHub privés devrait fonctionner.
npm install OWNER/REPO --save
apparaîtra dans package.json
comme: "REPO": "github:OWNER/REPO"
Et la résolution des repos privés dans la construction Heroku devrait également fonctionner.
en option, vous pouvez configurer un script postbuild pour désactiver le GITHUB_TOKEN
.
Vous pouvez utiliser dans le paquet.référentiel privé json avec exemple d'authentification ci-dessous:
https://usernamegit:passwordgit@github.com/reponame/web/tarball/branchname
En bref, ce n'est pas possible. La meilleure solution à ce problème que j'ai trouvé est d'utiliser le nouveau sous-arbre git . au moment de l'écriture, ils ne sont pas dans la source git officielle et doivent donc être installés manuellement mais ils seront inclus dans 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 gonfle la taille du repo mais une mise à jour est facile en faisant la commande ci-dessus avec gitsubtree pull.
Je l'ai déjà fait avec des modules de github. Npm accepte actuellement le nom du paquet ou un lien vers un fichier tar.gz
qui contient le paquet.
Par exemple si vous souhaitez utiliser express.js directement depuis Github (prenez 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).