node.js-Heroku上的NPM私有git模块

我正在尝试将我的应用程序部署到Heroku,但是我依靠使用一些私有git repos作为模块。 我这样做是为了在项目之间重用代码,例如 我有一个在多个应用程序中使用的自定义记录器。

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

问题是Heroku显然没有ssh访问此代码。 我找不到关于这个问题的任何东西。 理想情况下,Heroku具有一个公共密钥,我可以将其添加到模块中。

henry.oswald asked 2020-01-24T09:50:37Z
10个解决方案
66 votes

基本认证

GitHub支持基本身份验证:

"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)

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

您现在应该使用:

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

对于Github,您可以在此处生成一个新令牌:

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

应用程式密码(Bitbucket)

应用程序密码主要用于提供与不支持两因素身份验证的应用程序兼容的方式,您也可以将其用于此目的。 首先,创建一个应用密码,然后像这样指定您的依赖关系:

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

[不推荐使用]团队的API密钥(Bitbucket)

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

"dependencies" : {
    "my-module" : "git+https://<teamname>:<api-key>@bitbucket.org/team_name/repo_name.git"
}
Koen. answered 2020-01-24T09:51:41Z
37 votes

更新2016-03-26

如果您使用的是npm3,则描述的方法将不再起作用,因为npm3在运行GIT_SSH_KEY脚本之前会获取preinstall.sh中描述的所有模块。 这已被确认为错误。

官方的node.js Heroku构建包现在包括preinstall.shGIT_SSH_KEY,它们将分别在npm install之前和之后运行。 在所有情况下,都应使用这些脚本代替preinstallpostinstall,以同时支持npm2和npm3。

换句话说,您的preinstall.sh应该类似于:

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

我想出了迈克尔的替代方案,保留了(IMO)有利的要求,可将您的凭据置于源代码控制范围之外,而无需自定义buildpack。 这是出于对Michael链接的buildpack太过时而感到沮丧的证明。

解决方案是在npm的preinstall.shGIT_SSH_KEY脚本中而不是在buildpack中设置和拆除SSH环境。

请遵循以下指示:

  • 在您的仓库中创建两个脚本,我们将它们称为preinstall.shGIT_SSH_KEY
  • 使它们可执行(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 preinstall.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
  • 将以下内容添加到您的preinstall.sh

    preinstall.sh
  • 使用preinstall.sh生成私钥/公钥对。

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

在Heroku构建应用程序时,在npm安装依赖项之前,将运行preinstall.sh脚本。 这将从环境变量GIT_SSH_KEY的解码内容中创建一个私钥文件,并创建一个SSH配置文件以告诉SSH在连接到github.com时使用该文件。(如果要连接到Bitbucket,则更新2716597294257931931265中的preinstall.shbitbucket.org)。 然后,npm使用此SSH配置安装模块。 安装后,将删除私钥并擦除配置。

这样,Heroku可以通过SSH删除您的私有模块,同时将私有密钥保留在代码库之外。 如果您的私钥被泄露,因为它只是部署密钥的一半,您可以在GitHub上撤消公钥并重新生成密钥对。

顺便说一句,由于GitHub部署密钥具有读/写权限,因此,如果您将模块托管在GitHub组织中,则可以创建一个只读团队,并为其分配一个“部署”用户。 然后可以使用密钥对的公共半部分来配置部署用户。 这为您的模块增加了一层额外的安全性。

Tom Spencer answered 2020-01-24T09:54:24Z
13 votes

在git repo中使用纯文本密码确实是个坏主意,使用访问令牌更好,但是您仍然要非常小心。

"my_module": "git+https://ACCESS_TOKEN:x-oauth-basic@github.com/me/my_module.git"
Dom Barker answered 2020-01-24T09:54:44Z
13 votes

我创建了一个自定义的nodeJS buildpack,它将允许您指定一个SSH密钥,该密钥已在ssh-agent中注册,并在首次设置dynos时由npm使用。 它无缝地允许您将模块指定为cat id_rsa | base64 | pbcopy中的ssh url,如下所示:

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

要将您的应用设置为使用私钥:

  • 生成密钥:cat id_rsa | base64 | pbcopy(不输入密码。buildpack不支持带密码的密钥)
  • 将公用密钥添加到github:cat id_rsa | base64 | pbcopy(在OS X中)并将结果粘贴到github admin中
  • 将私钥添加到heroku应用的配置中:cat id_rsa | base64 | pbcopy,然后heroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
  • 按照项目中包含的heroku nodeJS buildpack README中的描述,设置您的应用程序以使用buildpack。 总之,最简单的方法是使用heroku config:set将特殊的config值设置为包含所需buildpack的存储库的github url。 我建议分叉我的版本并链接到您自己的github fork,因为我不承诺不更改自己的buildpack。

我的自定义buildpack可以在这里找到:[https://github.com/thirdiron/heroku-buildpack-nodejs],它适用于我的系统。 欢迎发表评论和请求。

Michael Lang answered 2020-01-24T09:55:31Z
6 votes

基于@fiznool的回答,我创建了一个buildpack来使用存储为环境变量的自定义ssh密钥解决此问题。 由于buildpack与技术无关,因此可以使用任何工具(例如php的composer,ruby的bundler,javascript的npm等)来下载依赖项:[https://github.com/simon0191/custom-ssh-key-buildpack ]

  1. 将构建包添加到您的应用程序:

    # 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
    
  2. 生成没有密码的新SSH密钥(假设您将其命名为deploy_key)

  3. 将公用密钥添加到您的专用存储库帐户。 例如:

    • Github:[https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/]

    • Bitbucket:[https://confluence.atlassian.com/bitbucket/add-an-ssh-key-to-an-account-302811853.html]

  4. 将私钥编码为base64字符串,并将其添加为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 环境变量。

  5. 制作一个逗号分隔的主机列表,并为其使用ssh密钥,并将其添加为heroku应用程序的2716601153235715715072环境变量。

    # 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. 部署您的应用程序并享受:)
Simon Soriano answered 2020-01-24T09:56:36Z
2 votes

这个答案很好[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 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
Eduard Bondarenko answered 2020-01-24T09:56:56Z
1 votes

我能够通过个人访问令牌在Heroku构建中设置Github私有存储库的解析。

  • 在此处生成Github访问令牌:[https://github.com/settings/tokens]
  • 将访问令牌设置为Heroku config var:GITHUB_TOKEN或通过Heroku仪表板
  • 添加GITHUB_TOKEN脚本:

    GITHUB_TOKEN
  • 将预构建脚本添加到GITHUB_TOKEN

    GITHUB_TOKEN

对于本地环境,我们也可以使用GITHUB_TOKEN,也可以将访问令牌添加到package.json文件中:

machine github.com
  login PASTE_GITHUB_USERNAME_HERE
  password PASTE_GITHUB_TOKEN_HERE

和安装私人github仓库应该可以。

GITHUB_TOKEN将在package.json中显示为:"REPO": "github:OWNER/REPO"

并且在Heroku构建中解析私人仓库也应该起作用。(可选)您可以设置一个构建后脚本来取消设置GITHUB_TOKEN

Michal Moravcik answered 2020-01-24T09:58:00Z
-2 votes

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

https://usernamegit:passwordgit@github.com/reponame/web/tarball/branchname
user1987237 answered 2020-01-24T09:58:19Z
-3 votes

简而言之,这是不可能的。 我想出的解决此问题的最佳方法是使用新的git子树。 在撰写本文时,它们不在官方的git源码中,因此需要手动安装,但它们将包含在v1.7.11中。 目前,它可通过自制软件和apt-get获得。 那是一种情况

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

这会增加仓库的大小,但是通过使用gitsubtree pull进行上述命令,更新很容易。

henry.oswald answered 2020-01-24T09:58:44Z
-4 votes

我之前使用github中的模块完成了此操作。 Npm当前接受包的名称或指向包含该包的tar.gz文件的链接。

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

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

因此,您需要找到一种方法来通过http(s)以2716604392245045036032文件的形式访问存储库。

TheHippo answered 2020-01-24T09:59:13Z
translate from https://stackoverflow.com:/questions/10869796/npm-private-git-module-on-heroku