简体   繁体   English

Heroku上的NPM私有git模块

[英]NPM private git module on Heroku

I am trying to deploy my app to Heroku however I rely on using some private git repos as modules. 我正在尝试将我的应用程序部署到Heroku,但我依赖于使用一些私有git repos作为模块。 I do this for code reuse between projects, eg I have a custom logger I use in multiple apps. 我这样做是为了在项目之间重用代码,例如我有一个我在多个应用程序中使用的自定义记录器。

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

The problem is Heroku obviously does not have ssh access to this code. 问题是Heroku显然没有ssh访问此代码。 I can't find anything on this problem. 我在这个问题上找不到任何东西。 Ideally Heroku have a public key I can can just add to the modules. 理想情况下Heroku有一个我可以添加到模块的公钥。

Basic auth 基本认证

GitHub has support for basic auth: GitHub支持基本身份验证:

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

As does BitBucket: 和BitBucket一样:

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

But having plain passwords in your package.json is probably not desired. 但是在package.json使用普通密码可能并不理想。

Personal access tokens (GitHub) 个人访问令牌(GitHub)

To make this answer more up-to-date, I would now suggest using a personal access token on GitHub instead of username/password combo. 为了使这个答案更新,我现在建议在GitHub上使用个人访问令牌而不是用户名/密码组合。

You should now use: 你现在应该使用:

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

For Github you can generate a new token here: 对于Github,您可以在此处生成新令牌:

https://github.com/settings/tokens https://github.com/settings/tokens

App passwords (Bitbucket) 应用密码(Bitbucket)

App passwords are primarily intended as a way to provide compatibility with apps that don't support two-factor authentication, and you can use them for this purpose as well. 应用程序密码主要用于提供与不支持双因素身份验证的应用程序的兼容性,您也可以将它们用于此目的。 First, create an app password , then specify your dependency like this: 首先, 创建一个应用程序密码 ,然后像这样指定您的依赖关系:

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

[Deprecated] API key for teams (Bitbucket) [已弃用]团队的API密钥(Bitbucket)

For BitBucket you can generate an API Key on the Manage Team page and then use this URL: 对于BitBucket,您可以在Manage Team页面上生成API Key,然后使用以下URL:

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

Update 2016-03-26 更新2016-03-26

The method described no longer works if you are using npm3, since npm3 fetches all modules described in package.json before running the preinstall script. 如果使用npm3,则描述的方法不再有效,因为npm3在运行preinstall脚本之前获取package.json描述的所有模块。 This has been confirmed as a bug . 已被确认为一个错误

The official node.js Heroku buildpack now includes heroku-prebuild and heroku-postbuild , which will be run before and after npm install respectively. 官方node.js Heroku buildpack现在包括heroku-prebuildheroku-postbuild ,它们将分别在npm install之前和之后npm install You should use these scripts instead of preinstall and postinstall in all cases, to support both npm2 and npm3. 在所有情况下,您应该使用这些脚本而不是preinstallpostinstall ,以支持npm2和npm3。

In other words, your package.json should resemble: 换句话说,你的package.json应该类似于:

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

I've come up with an alternative to Michael's answer, retaining the (IMO) favourable requirement of keeping your credentials out of source control, whilst not requiring a custom buildpack. 我想出了迈克尔答案的替代方案,保留了(IMO)有利的要求,即保持您的凭证不受源代码控制,同时不需要自定义构建包。 This was borne out of frustration that the buildpack linked by Michael is rather out of date. 这是因为迈克尔链接buildpack已经过时而感到沮丧。

The solution is to setup and tear down the SSH environment in npm's preinstall and postinstall scripts, instead of in the buildpack. 解决方案是在npm的preinstallpostinstall脚本中设置和拆除SSH环境,而不是在buildpack中。

Follow these instructions: 请遵循以下说明:

  • Create two scripts in your repo, let's call them preinstall.sh and postinstall.sh . 在repo中创建两个脚本,我们称之为preinstall.shpostinstall.sh
  • Make them executable ( chmod +x *.sh ). 使它们可执行( chmod +x *.sh )。
  • Add the following to preinstall.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
  • Add the following to postinstall.sh : 将以下内容添加到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
  • Add the following to your package.json : 将以下内容添加到package.json

     "scripts": { "preinstall": "bash preinstall.sh", "postinstall": "bash postinstall.sh" } 
  • Generate a private/public key pair using ssh-agent . 使用ssh-agent生成私钥/公钥对。

  • Add the public key as a deploy key on Github. 在Github上添加公钥作为部署密钥。
  • Create a base64 encoded version of your private key, and set it as the Heroku config var GIT_SSH_KEY . 创建私钥的base64编码版本,并将其设置为Heroku config var GIT_SSH_KEY
  • Commit and push your app to Github. 提交并将您的应用推送到Github。

When Heroku builds your app, before npm installs your dependencies, the preinstall.sh script is run. 当Heroku构建您的应用程序时,在npm安装依赖项之前,会运行preinstall.sh脚本。 This creates a private key file from the decoded contents of the GIT_SSH_KEY environment variable, and creates an SSH config file to tell SSH to use this file when connecting to github.com . 这将从GIT_SSH_KEY环境变量的解码内容创建私钥文件,并创建SSH配置文件以告知SSH在连接到github.com时使用此文件。 (If you are connecting to Bitbucket instead, then update the Host entry in preinstall.sh to bitbucket.org ). (如果您要连接到Bitbucket,请将preinstall.shHost条目更新到bitbucket.org )。 npm then installs the modules using this SSH config. 然后npm使用此SSH配置安装模块。 After installation, the private key is removed and the config is wiped. 安装后,将删除私钥并擦除配置。

This allows Heroku to pull down your private modules via SSH, while keeping the private key out of the codebase. 这允许Heroku通过SSH下载您的私有模块,同时保持私钥不在代码库中。 If your private key becomes compromised, since it is just one half of a deploy key, you can revoke the public key in GitHub and regenerate the keypair. 如果您的私钥被泄露,因为它只是部署密钥的一半,您可以撤销GitHub中的公钥并重新生成密钥对。

As an aside, since GitHub deploy keys have read/write permissions, if you are hosting the module in a GitHub organization, you can instead create a read-only team and assign a 'deploy' user to it. 顺便说一句,由于GitHub部署密钥具有读/写权限,如果您在GitHub组织中托管该模块,您可以创建一个只读团队并为其分配一个“部署”用户。 The deploy user can then be configured with the public half of the keypair. 然后,可以使用密钥对的公共一半配置部署用户。 This adds an extra layer of security to your module. 这为您的模块增加了额外的安全层。

在你的git repo中使用纯文本密码是一个非常糟糕的主意,使用访问令牌会更好,但你仍然需要非常小心。

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

I created a custom nodeJS buildpack that will allow you to specify an SSH key that is registered with ssh-agent and used by npm when dynos are first setup. 我创建了一个自定义nodeJS buildpack,它允许您指定一个使用ssh-agent注册的SSH密钥,并在首次设置dynos时由npm使用。 It seamlessly allows you to specify your module as an ssh url in your package.json like shown: 它无缝地允许您在package.json中将模块指定为ssh url,如下所示:

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

To setup your app to use your private key: 要设置您的应用以使用您的私钥:

  • Generate a key: ssh-keygen -t rsa -C "your_email@example.com" (Enter no passphrase. The buildpack does not support keys with passphrases) 生成密钥: ssh-keygen -t rsa -C "your_email@example.com" (输入no passphrase.buildpack不支持带密码的密钥)
  • Add the public key to github: pbcopy < ~/.ssh/id_rsa.pub (in OS X) and paste the results into the github admin 将公钥添加到github: pbcopy < ~/.ssh/id_rsa.pub (在OS X中)并将结果粘贴到github管理员
  • Add the private key to your heroku app's config: cat id_rsa | base64 | pbcopy 将私钥添加到您的heroku应用程序的配置: cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy cat id_rsa | base64 | pbcopy , then heroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name cat id_rsa | base64 | pbcopy ,然后是heroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
  • Setup your app to use the buildpack as described in the heroku nodeJS buildpack README included in the project. 设置您的应用程序以使用buildpack,如项目中包含的heroku nodeJS buildpack README中所述。 In summary the simplest way is to set a special config value with heroku config:set to the github url of the repository containing the desired buildpack. 总之,最简单的方法是使用heroku config设置一个特殊的配置值:设置为包含所需buildpack的存储库的github url。 I'd recommend forking my version and linking to your own github fork, as I'm not promising to not change my buildpack. 我建议分配我的版本并链接到你自己的github fork,因为我不承诺不改变我的buildpack。

My custom buildpack can be found here: https://github.com/thirdiron/heroku-buildpack-nodejs and it works for my system. 我的自定义buildpack可以在这里找到: https//github.com/thirdiron/heroku-buildpack-nodejs ,它适用于我的系统。 Comments and pull requests are more than welcome. 评论和拉取请求非常受欢迎。

Based on the answer from @fiznool I created a buildpack to solve this problem using a custom ssh key stored as an environment variable. 基于@fiznool的答案,我使用存储为环境变量的自定义ssh密钥创建了一个buildpack来解决这个问题。 As the buildpack is technology agnostic, it can be used to download dependencies using any tool like composer for php, bundler for ruby, npm for javascript, etc: https://github.com/simon0191/custom-ssh-key-buildpack 由于buildpack与技术无关,因此可以使用任何工具来下载依赖项,例如用于php的composer,用于ruby的bundler,用于javascript的npm等等: https//github.com/simon0191/custom-ssh-key-buildpack

  1. Add the buildpack to your app: 将buildpack添加到您的应用程序:

     $ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack 
  2. Generate a new SSH key without passphrase (lets say you named it deploy_key) 生成一个没有密码短语的新SSH密钥(假设您将其命名为deploy_key)

  3. Add the public key to your private repository account. 将公钥添加到您的私有存储库帐户。 For example: 例如:

  4. Encode the private key as a base64 string and add it as the CUSTOM_SSH_KEY environment variable of the heroku app. 将私钥编码为base64字符串,并将其添加为heroku应用程序的CUSTOM_SSH_KEY环境变量。

  5. Make a comma separated list of the hosts for which the ssh key should be used and add it as the CUSTOM_SSH_KEY_HOSTS environment variable of the heroku app. 制作以逗号分隔的主机列表,其中应使用ssh密钥,并将其添加为heroku应用程序的CUSTOM_SSH_KEY_HOSTS环境变量。

     # 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. Deploy your app and enjoy :) 部署您的应用程序并享受:)

This answer is good https://stackoverflow.com/a/29677091/6135922 , but I changed a little bit preinstall script. 这个答案很好https://stackoverflow.com/a/29677091/6135922 ,但我更改了一些预安装脚本。 Hope this will help someone. 希望这会对某人有所帮助。

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

I was able to setup resolving of Github private repositories in Heroku build via Personal access tokens. 我能够通过个人访问令牌在Heroku构建中设置Github私有存储库的解析。

  • Generate Github access token here: https://github.com/settings/tokens 在此处生成Github访问令牌: https//github.com/settings/tokens
  • Set access token as Heroku config var: heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name or via Heroku Dashboard 将访问令牌设置为Heroku配置var: heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name或通过Heroku Dashboard
  • Add heroku-prebuild.sh 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 
  • add the prebuild script to package.json : 将prebuild脚本添加到package.json

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

For local environment we can also use git config ... or we can add the access token to ~/.netrc file: 对于本地环境,我们也可以使用git config ...或者我们可以将访问令牌添加到~/.netrc文件中:

machine github.com
  login PASTE_GITHUB_USERNAME_HERE
  password PASTE_GITHUB_TOKEN_HERE

and installing private github repos should work. 并安装私有github repos应该工作。

npm install OWNER/REPO --save will appear in package.json as: "REPO": "github:OWNER/REPO" npm install OWNER/REPO --save将出现在package.json中: "REPO": "github:OWNER/REPO"

and resolving private repos in Heroku build should also work. 并解决Heroku构建中的私有回购也应该有效。 optionally you can setup a postbuild script to unset the GITHUB_TOKEN . 您可以选择设置postbuild脚本来取消设置GITHUB_TOKEN

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

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

In short it is not possible. 简而言之,这是不可能的。 The best solution to this problem I came up with is to use the new git subtree 's. 我想出的这个问题的最佳解决方案是使用新的git子树 At the time of writing they are not in the official git source and so needs to be installed manual but they will be included in v1.7.11. 在撰写本文时,它们不在官方git源代码中,因此需要手动安装,但它们将包含在v1.7.11中。 At the moment it is available on homebrew and apt-get. 目前它可以在自制软件和apt-get上使用。 it is then a case of doing 这是一个做的事情

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

this bulks out the repo size but an update is easy by doing the command above with gitsubtree pull. 这会使回购大小变大,但通过gitsubtree pull执行上述命令可以轻松实现更新。

I have done this before with modules from github. 我之前用github的模块做过这个。 Npm currently accepts the name of the package or a link to a tar.gz file which contains the package. Npm目前接受包的名称或包含该包的tar.gz文件的链接。

For example if you want to use express.js directly from Github (grab the link via the download section) you could do: 例如,如果你想直接从Github使用express.js(通过下载部分获取链接),你可以这样做:

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

So you need to find a way to access you repository as a tar.gz file via http(s). 因此,您需要找到一种通过http(s)访问存储库作为tar.gz文件的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM