Heroku上的NPM私人git模块

我试图将我的应用程序部署到Heroku,但我依靠使用一些私人的git回购作为模块。 我这样做代码项目之间的重用,例如我有一个自定义logging器,我在多个应用程序中使用。

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

问题是Heroku显然没有ssh访问这个代码。 我在这个问题上找不到任何东西。 理想情况下,Heroku有一个公钥,我可以添加到模块。

基本身份validation

GitHub支持基本身份validation:

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

BitBucket也一样:

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

但是在你的package.json有简单的密码可能是不希望的。

个人访问令牌(GitHub)

为了使这个答案更新,我现在build议在GitHub上使用个人访问令牌 ,而不是用户名/密码组合。

你现在应该使用:

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

对于Github,你可以在这里生成一个新的标记:

https://github.com/settings/tokens

应用程序密码(Bitbucket)

应用程序密码主要是为了兼容不支持双因素身份validation的应用程序,您也可以将其用于此目的。 首先, 创build一个应用程序的密码 ,然后指定你的依赖像这样:

 "dependencies" : { "my-module": "git+https://<username>:<app-password>@bitbucket.org/my_bitbucket_account/my_repo.git" } 

[已弃用的] API密钥(Bitbucket)

对于BitBucket,您可以在“pipe理团队”页面上生成API密钥,然后使用以下URL:

 "dependencies" : { "my-module" : "git+https://<teamname>:<api-key>@bitbucket.org/team_name/repo_name.git" } 

2016-03-26更新

如果您使用npm3,则描述的方法不再有效,因为npm3在运行preinstall脚本之前获取package.json描述的所有模块。 这已被确认为一个错误 。

官方的node.js Heroku buildpack现在包含了分别在npm install之前和之后运行的heroku-prebuildheroku-postbuild 。 您应该使用这些脚本,而不是在所有情况下进行preinstallpostinstall ,以同时支持npm2和npm3。

换句话说,你的package.json应该类似于:

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

我想出了一个替代迈克尔的答案,保留(IMO)有利的要求,保持您的凭据不受源代码pipe理,而不需要定制的buildpack。 这是由于Michael所连接的buildpack已经过时而感到沮丧的结果。

解决scheme是在npm的preinstallpostinstall脚本中设置和拆除SSH环境,而不是在buildpack中。

遵循这些指示:

  • 在你的仓库中创build两个脚本,我们称它们为preinstall.shpostinstall.sh
  • 使它们可执行( chmod +x *.sh )。
  • 将以下内容添加到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 
  • 将以下内容添加到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 
  • 将以下内容添加到你的package.json

     "scripts": { "preinstall": "bash preinstall.sh", "postinstall": "bash postinstall.sh" } 
  • 使用ssh-agent生成私钥/公钥对。

  • 在Github上添加公钥作为部署密钥。
  • 创build一个base64编码版本的私钥,并将其设置为Heroku config var GIT_SSH_KEY
  • 提交并将您的应用程序推送到Github。

当Heroku构build您的应用程序时,在npm安装您的依赖关系之前,运行preinstall.sh脚本。 这将从GIT_SSH_KEY环境variables的解码内容中创build一个私钥文件,并创build一个SSHconfiguration文件来告诉SSH在连接到github.com时使用这个文件。 (如果您连接到Bitbucket,请将preinstall.shHost条目更新到bitbucket.org )。 npm然后使用这个SSHconfiguration安装模块。 安装后,私钥被删除,configuration被清除。

这使得Heroku可以通过SSH下拉你的私有模块,同时保持私钥不在代码库中。 如果您的私钥遭到破坏,因为它只是部署密钥的一半,您可以撤消GitHub中的公钥并重新生成密钥对。

另外,由于GitHub部署密钥具有读/写权限,如果您将模块托pipe在GitHub组织中,则可以创build一个只读组,并为其分配“部署”用户。 部署用户可以configuration公钥的一半。 这为您的模块增加了额外的安全层。

在你的git仓库中使用纯文本密码是一个不错的主意,使用访问令牌更好,但是你仍然要特别小心。

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

我创build了一个自定义的nodeJS buildpack,它允许你指定一个SSH密钥,这个密钥是在ssh-agent注册的,当dynos第一次安装的时候由npm使用。 它无缝地允许你在你的package.json指定你的模块作为ssh url,如下所示:

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

要设置您的应用程序以使用您的私钥:

  • 生成密钥: ssh-keygen -t rsa -C "your_email@example.com" (不input密码,buildpack不支持带密码的密钥)
  • 将公钥添加到github中: pbcopy < ~/.ssh/id_rsa.pub (在OS X中)并将结果粘贴到github admin
  • 将私钥添加到你的heroku应用的configuration: cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy ,然后heroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
  • 按照项目中包含的heroku nodeJS buildpack自述文件中所述设置应用程序以使用buildpack。 总而言之,最简单的方法是使用heroku config设置一个特殊的configuration值:设置为包含所需buildpack的存储库的github url。 我build议分叉我的版本和链接到自己的github分叉,因为我不承诺不改变我的buildpack。

我的自定义buildpack可以在这里find: https : //github.com/thirdiron/heroku-buildpack-nodejs和它适用于我的系统。 评论和拉请求是比欢迎。

基于@fiznool的答案,我创build了一个buildpack来解决这个问题,使用一个自定义的ssh密钥存储为一个环境variables。 由于buildpack是技术不可知论的,它可以用来下载依赖使用任何工具,如composer php的PHP,ruby的捆绑器,JavaScript的npm等, https : //github.com/simon0191/custom-ssh-key-buildpack

  1. 将buildpack添加到您的应用程序中:

     $ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack 
  2. 生成一个新的SSH密钥(可以说你把它命名为deploy_key)

  3. 将密钥添加到您的私有存储库

  4. CUSTOM_SSH_KEYCUSTOM_SSH_KEY_HOSTS环境variables添加到您的heroku应用程序

     $ heroku config:set CUSTOM_SSH_KEY=$(base64 --input ~/.ssh/deploy_key.pub) CUSTOM_SSH_KEY_HOSTS=bitbucket.org,github.com 
  5. 部署你的应用程序,并享受:)

这个答案很好https://stackoverflow.com/a/29677091/6135922 ,但我改变了一点点的预安装脚本。 希望这会帮助别人。

 #!/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"\ " 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 

我能够通过个人访问令牌设置解决在Heroku构buildGithub私人存储库。

  • 在这里生成Github访问令牌: https : //github.com/settings/tokens
  • 将访问令牌设置为Heroku config var: heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name或者通过Heroku Dashboard
  • 添加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 
  • 将prebuild脚本添加到package.json

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

对于本地环境,我们也可以使用git config ...或者我们可以将访问令牌添加到~/.netrc文件中:

 machine github.com login PASTE_GITHUB_USERNAME_HERE password PASTE_GITHUB_TOKEN_HERE 

并安装私人github回购应该工作。

npm install OWNER/REPO --save会出现在package.json中: "REPO": "github:OWNER/REPO"

解决Herokubuild设中的私人回购也应该起作用。 您可以select设置一个postbuild脚本来取消设置GITHUB_TOKEN

您可以在package.json私有存储库中使用以下身份validation示例:

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

我以前用github的模块做过这个。 Npm目前接受包的名称或包含包的tar.gz文件的链接。

例如,如果你想从Github直接使用express.js(通过下载部分获取链接),你可以这样做:

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

所以你需要find一种方法来通过http(s)作为tar.gz文件访问你的仓库。

总之这是不可能的。 解决这个问题的最好方法就是使用新的git子树 。 在撰写本文时,他们不在官方的git源代码中,因此需要手动安装,但它们将包含在v1.7.11中。 目前它在自制和apt-get上可用。 那么就是一个例子

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

这使得回购大小变大,但通过使用gitsubtree pull执行上面的命令,更新很容易。