我正在尝试将我的应用程序部署到Heroku,但是我依赖于使用一些私有的Git仓库作为模块。我这样做是为了在项目之间重复使用代码,例如,我有一个自定义的日志记录器,我在多个应用程序中使用它。
"logger":"git+ssh://git@bitbucket.org..............#master"
问题在于Heroku显然没有对这段代码进行ssh访问权限。我在这个问题上找不到任何信息。理想情况下,Heroku会有一把公钥,我只需将其添加到模块中。
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 上使用个人访问令牌代替用户名/密码组合。请参考如何使用个人访问令牌。
您现在应该使用:
"dependencies" : {
"my-module" : "git+https://<username>:<token>@github.com/my_github_account/my_repo.git"
}
对于Github,您可以在这里生成新令牌:
https://github.com/settings/tokens
应用程序密码主要用于提供与不支持双因素身份验证的应用程序兼容性的方式,您也可以将其用于此目的。首先创建一个应用程序密码,然后像这样指定您的依赖项:
"dependencies" : {
"my-module": "git+https://<username>:<app-password>@bitbucket.org/my_bitbucket_account/my_repo.git"
}
您可以在“管理团队”页面上生成 Bitbucket 的 API 密钥,然后使用此 URL:
"dependencies" : {
"my-module" : "git+https://<teamname>:<api-key>@bitbucket.org/team_name/repo_name.git"
}
git+https://<team-name>:<api-key>@bitbucket.org/<team-name>/<repo_name>.git
。请注意不要更改原意。 - Grofit更新时间 2016-03-26
如果您正在使用npm3,则本文描述的方法已不再适用,因为npm3在运行preinstall
脚本之前会获取 package.json
中描述的所有模块,该问题已确认为bug。
官方的node.js Heroku构建包现在包括heroku-prebuild
和 heroku-postbuild
,分别在npm install
之前和之后运行。 您应该在所有情况下都使用这些脚本来替代preinstall
和postinstall
,以支持npm2和npm3。
换句话说,您的package.json
应类似于:
"scripts": {
"heroku-prebuild": "bash preinstall.sh",
"heroku-postbuild": "bash postinstall.sh"
}
我想出了一种替代Michael答案的方法,保留了(在我看来)有利的要求,即将您的凭据保持不在源代码控制下,同时不需要自定义构建包。这是因为我对Michael链接的构建包感到失望,因为它已经过时了。
解决方案是在npm的preinstall
和postinstall
脚本中设置和撤销SSH环境,而不是在构建包中。
按照以下说明操作:
preinstall.sh
和postinstall.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
Add the following to your package.json
:
"scripts": {
"preinstall": "bash preinstall.sh",
"postinstall": "bash postinstall.sh"
}
Generate a private/public key pair using ssh-agent
.
GIT_SSH_KEY
.preinstall.sh
脚本。这将从GIT_SSH_KEY
环境变量的解码内容创建私钥文件,并创建一个SSH配置文件,告诉SSH在连接到github.com
时使用此文件。(如果您连接的是Bitbucket,则更新preinstall.sh
中的Host
条目为bitbucket.org
)。然后,npm使用此SSH配置安装模块。安装完成后,将删除私钥并擦除配置。cat /path/to/private/key | base64 > output.txt
命令。然后删除任何 \n
(换行符),并将其粘贴到我的 Heroku 设置中。 - PeterGIT_SSH_01
、GIT_SSH_02
等等 - 只需记得相应地修改脚本以使用正确的环境变量即可。 - Tom Spencer在您的git repo中拥有明文密码是一个非常糟糕的想法,使用访问令牌会更好,但您仍然需要非常小心。
"my_module": "git+https://ACCESS_TOKEN:x-oauth-basic@github.com/me/my_module.git"
我创建了一个自定义的nodeJS构建包,允许您指定在dynos第一次设置时由ssh-agent注册并由npm使用的SSH密钥。它可以无缝地允许您在package.json
中指定您的模块作为ssh url,如下所示:
"private_module": "git+ssh://git@github.com:me/my_module.git"
ssh-keygen -t rsa -C "your_email@example.com"
(不输入密码。该 buildpack 不支持带有密码的密钥)pbcopy < ~/.ssh/id_rsa.pub
(在 OS X 中),并将结果粘贴到 GitHub 管理员中cat id_rsa | base64 | pbcopy
,然后 heroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
我的定制 buildpack 可在此处找到:https://github.com/thirdiron/heroku-buildpack-nodejs,它适用于我的系统。欢迎评论和拉取请求。
根据@fiznool的回答,我创建了一个构建包来解决这个问题,使用存储为环境变量的自定义ssh密钥。由于该构建包是技术无关的,因此可以使用任何工具(如php的composer,ruby的bundler,javascript的npm)来下载依赖项:https://github.com/simon0191/custom-ssh-key-buildpack
Add the buildpack to your app:
$ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack
Generate a new SSH key without passphrase (lets say you named it deploy_key)
Add the public key to your private repository account. For example:
Encode the private key as a base64 string and add it as the CUSTOM_SSH_KEY
environment variable of the heroku app.
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.
# 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
--input ~/.ssh/deploy_key
。你在脚本中解码了私钥的base64,请纠正一下。 - gmuraleekrishna--input
标志取决于您使用的 base64 版本。例如,在 macOS 中需要它,但在 Ubuntu 14.04 中该标志无法识别。 - Simon Soriano我能够通过个人访问令牌,在Heroku构建中设置解析Github私有存储库。
heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name
or via Heroku DashboardAdd 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
add the prebuild script to 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构建中解析私有仓库也是有效的。你可以选择设置一个后置脚本来取消GITHUB_TOKEN
。
这个答案很好(原文链接),但我稍微更改了一下预安装脚本。希望这能对某些人有所帮助。
#!/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
您可以在 package.json 中使用以下身份验证示例的私有存储库:
https://usernamegit:passwordgit@github.com/reponame/web/tarball/branchname
git subtree add -P /node_modules/someprivatemodue git@github.......someprivatemodule {master|tag|commit}
这会增加仓库的大小,但通过使用gitsubtree pull命令进行更新非常容易。
我以前用过来自Github的模块完成了这个。Npm目前接受包的名称或包含该包的tar.gz
文件的链接。
例如,如果您想直接从Github使用express.js(通过下载部分获取链接),您可以执行以下操作:
"dependencies" : {
"express" : "https://github.com/visionmedia/express/tarball/2.5.9"
}
所以你需要找到一种通过http(s)访问你的代码库的tar.gz
文件的方法。
heroku keys:add ~/.ssh/id_rsa.pub
。理论上这应该是可行的,但是git push heroku master
仍然会出现“主机密钥验证失败”的错误。你在六月份问过这个问题,那时你找到答案了吗? - lefnire