56

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

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

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

4

10 回答 10

75

基本认证

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"
}
于 2012-11-12T23:35:27.107 回答
44

2016-03-26 更新

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

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

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

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

我提出了迈克尔的答案的替代方案,保留了(IMO)将您的凭据排除在源代码控制之外的有利要求,同时不需要自定义构建包。这是由于 Michael 链接的 buildpack已经过时而感到沮丧。

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

请遵循以下说明:

  • 在您的存储库中创建两个脚本,我们将它们命名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 上的部署密钥。
  • 创建你的私钥的 base64 编码版本,并将其设置为 Heroku config var GIT_SSH_KEY
  • 提交并将您的应用推送到 Github。

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

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

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

于 2015-04-16T14:02:04.200 回答
15

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

"my_module": "git+https://ACCESS_TOKEN:x-oauth-basic@github.com/me/my_module.git"
于 2013-12-04T14:42:36.437 回答
14

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

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

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

  • 生成密钥:(ssh-keygen -t rsa -C "your_email@example.com"不输入密码。buildpack 不支持带密码的密钥)
  • 将公钥添加到 github:(pbcopy < ~/.ssh/id_rsa.pub在 OS X 中)并将结果粘贴到 github admin
  • 将私钥添加到您的 heroku 应用程序的 config: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 设置一个特殊的配置值到包含所需构建包的存储库的 github url。我建议分叉我的版本并链接到您自己的 github fork,因为我不保证不会更改我的 buildpack。

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

于 2014-04-03T01:40:44.553 回答
6

根据@fiznool 的回答,我创建了一个 buildpack 来使用存储为环境变量的自定义 ssh 密钥来解决这个问题。由于 buildpack 与技术无关,它可用于使用任何工具下载依赖项,如 php 的 composer、ruby 的 bundler、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. 将私钥编码为 base64 字符串,并将其添加为CUSTOM_SSH_KEYheroku 应用程序的环境变量。

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

    # 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. 部署您的应用程序并享受 :)
于 2017-02-24T18:01:02.357 回答
3

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

  • 在此处生成 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
    
  • 将预构建脚本添加到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"

并在 Heroku 构建中解决私人回购也应该有效。可选地,您可以设置一个 postbuild 脚本来取消设置GITHUB_TOKEN.

于 2016-09-09T14:38:42.150 回答
2

这个答案很好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
于 2016-09-01T18:29:44.770 回答
-2

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

https://usernamegit:passwordgit@github.com/reponame/web/tarball/branchname
于 2013-01-17T13:15:39.647 回答
-4

简而言之,这是不可能的。我想出的这个问题的最佳解决方案是使用新的git subtree。在撰写本文时,它们不在官方 git 源中,因此需要手动安装,但它们将包含在 v1.7.11 中。目前它可以在 homebrew 和 apt-get 上使用。然后就是这样做的情况

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

这会扩大 repo 的大小,但是通过使用 gitsubtree pull 执行上面的命令可以轻松进行更新。

于 2012-06-12T18:35:43.923 回答
-6

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

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

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

tar.gz因此,您需要找到一种通过 http(s)将存储库作为文件访问的方法。

于 2012-06-04T14:33:46.623 回答