node.js - node - npm heroku
Módulo de git privado de NPM en Heroku (10)
Estoy intentando implementar mi aplicación en Heroku, sin embargo, confío en usar algunos repositorios git privados como módulos. Lo hago para la reutilización de código entre proyectos, por ejemplo, tengo un registrador personalizado que uso en múltiples aplicaciones.
"logger":"git+ssh://[email protected]..............#master"
El problema es que Heroku obviamente no tiene acceso ssh a este código. No puedo encontrar nada sobre este problema. Idealmente, Heroku tiene una clave pública que puedo agregar a los módulos.
Autorización básica
GitHub tiene soporte para autenticación básica:
"dependencies" : {
"my-module" : "git+https://my_username:[email protected]/my_github_account/my_repo.git"
}
Como lo hace BitBucket:
"dependencies" : {
"my-module": "git+https://my_username:[email protected]/my_bitbucket_account/my_repo.git"
}
Pero tener contraseñas simples en su package.json
. package.json
probablemente no sea deseado.
Tokens de acceso personal (GitHub)
Para que esta respuesta esté más actualizada, ahora sugiero usar un token de acceso personal en GitHub en lugar de un nombre de usuario / combinación de contraseña.
Ahora deberías usar:
"dependencies" : {
"my-module" : "git+https://<username>:<token>@github.com/my_github_account/my_repo.git"
}
Para Github puedes generar un nuevo token aquí:
https://github.com/settings/tokens
Contraseñas de la aplicación (Bitbucket)
Las contraseñas de aplicaciones están pensadas principalmente como una forma de proporcionar compatibilidad con aplicaciones que no admiten la autenticación de dos factores, y también puede usarlas para este propósito. Primero, crea una contraseña de la aplicación , luego especifica tu dependencia de esta manera:
"dependencies" : {
"my-module": "git+https://<username>:<app-password>@bitbucket.org/my_bitbucket_account/my_repo.git"
}
[Desaprobada] clave de API para equipos (Bitbucket)
Para BitBucket, puede generar una clave API en la página Administrar equipo y luego usar esta URL:
"dependencies" : {
"my-module" : "git+https://<teamname>:<api-key>@bitbucket.org/team_name/repo_name.git"
}
Basado en la respuesta de @fiznool, creé un buildpack para resolver este problema usando una clave ssh personalizada almacenada como una variable de entorno. Como el buildpack es independiente de la tecnología, se puede usar para descargar dependencias usando cualquier herramienta como compositor para php, bundler para ruby, npm para javascript, etc .: https://github.com/simon0191/custom-ssh-key-buildpack
Agrega el paquete de construcción a tu aplicación:
$ heroku buildpacks:add --index 1 https://github.com/simon0191/custom-ssh-key-buildpack
Genere una nueva clave SSH sin frase de contraseña (digamos que lo llamó deploy_key)
Agregue la clave pública a su cuenta privada de repositorio. Por ejemplo:
Codifique la clave privada como una cadena base64 y agréguela como la variable de entorno
CUSTOM_SSH_KEY
de la aplicación heroku.Haga una lista separada por comas de los hosts para los cuales se debe usar la clave ssh y agréguela como la variable de entorno
CUSTOM_SSH_KEY_HOSTS
de la aplicación 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
- Implementa tu aplicación y disfruta :)
Creé un buildpack de nodeJS personalizado que le permitirá especificar una clave SSH que está registrada con ssh-agent y utilizada por npm cuando se configuran los dynos por primera vez. Perfectamente le permite especificar su módulo como una url ssh en su package.json
. package.json
como se muestra:
"private_module": "git+ssh://[email protected]:me/my_module.git"
Para configurar su aplicación para usar su clave privada:
- Genere una clave:
ssh-keygen -t rsa -C "[email protected]"
(No ingrese frase de contraseña. El buildpack no admite claves con frases de contraseña) - Agregue la clave pública a github:
pbcopy < ~/.ssh/id_rsa.pub
(en OS X) y pegue los resultados en el administrador de github - Agregue la clave privada a la configuración de su aplicación heroku:
cat id_rsa | base64 | pbcopy
cat id_rsa | base64 | pbcopy
cat id_rsa | base64 | pbcopy
, luegoheroku config:set GIT_SSH_KEY=<paste_here> --app your-app-name
- Configure su aplicación para usar el buildpack como se describe en el archivo heroku nodeJS buildpack README incluido en el proyecto. En resumen, la forma más sencilla es establecer un valor de configuración especial con heroku config: establecer en la url github del repositorio que contiene el buildpack deseado. Recomiendo bifurcar mi versión y vincularla a su propia bifurcación de github, ya que no prometo no cambiar mi buildpack.
Mi buildpack personalizado se puede encontrar aquí: https://github.com/thirdiron/heroku-buildpack-nodejs y funciona para mi sistema. Los comentarios y las solicitudes de extracción son más que bienvenidos.
En resumen, no es posible. La mejor solución a este problema que se me ocurrió es usar el nuevo subárbol de git . En el momento de escribir estas líneas, no están en la fuente oficial de GIT, por lo que deben instalarse manualmente, pero se incluirán en v1.7.11. Por el momento, está disponible en homebrew y apt-get. entonces es un caso de hacer
git subtree add -P /node_modules/someprivatemodue [email protected] {master|tag|commit}
esto amplía el tamaño del repositorio, pero una actualización es fácil al hacer el comando anterior con gitsubtree pull.
Es realmente una mala idea tener contraseñas de texto sin formato en tu repo de git, usar un token de acceso es mejor, pero aún así querrás ser muy cuidadoso.
"my_module": "git+https://ACCESS_TOKEN:[email protected]/me/my_module.git"
Esta respuesta es buena https://.com/a/29677091/6135922 , pero cambié un poco de script de preinstalación. Espero que esto ayude a alguien.
#!/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 [email protected]
fi
He hecho esto antes con módulos de github. Npm acepta actualmente el nombre del paquete o un enlace a un archivo tar.gz
que contiene el paquete.
Por ejemplo, si quieres usar express.js directamente de Github (agarra el enlace a través de la sección de descarga), podrías hacer:
"dependencies" : {
"express" : "https://github.com/visionmedia/express/tarball/2.5.9"
}
Por lo tanto, debe encontrar una forma de acceder a su repositorio como un archivo tar.gz
través de http (s).
Pude configurar la resolución de repositorios privados de Github en la compilación de Heroku a través de tokens de acceso personal.
- Genera el token de acceso de Github aquí: https://github.com/settings/tokens
- Establecer el token de acceso como configuración de Heroku var:
heroku config:set GITHUB_TOKEN=<paste_here> --app your-app-name
o a través del Tablero de Heroku Añadir el 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 [email protected]: fi
agregue el script prebuild a
package.json
:"scripts": { "heroku-prebuild": "bash heroku-prebuild.sh" }
Para el entorno local también podemos usar git config ...
o podemos agregar el token de acceso al archivo ~/.netrc
:
machine github.com
login PASTE_GITHUB_USERNAME_HERE
password PASTE_GITHUB_TOKEN_HERE
y la instalación de repositorios github privados debería funcionar.
npm install OWNER/REPO --save
aparecerá en package.json
como: "REPO": "github:OWNER/REPO"
y la resolución de repositorios privados en la compilación de Heroku también debería funcionar. opcionalmente puede configurar un script de postconstrucción para desarmar el GITHUB_TOKEN
.
Puede usarlo en el repositorio privado package.json con el siguiente ejemplo de autenticación:
https://usernamegit:[email protected]/reponame/web/tarball/branchname
Actualización 2016-03-26
El método descrito ya no funciona si está usando npm3, ya que npm3 recupera todos los módulos descritos en package.json
antes de ejecutar el script de preinstall
. Esto ha sido confirmado como un error .
El buildpack oficial de node.js Heroku ahora incluye heroku-prebuild
y heroku-postbuild
, que se ejecutarán antes y después de la npm install
respectivamente. Debe usar estos scripts en lugar de preinstall
y postinstall
en todos los casos, para admitir tanto npm2 como npm3.
En otras palabras, su package.json
debería parecerse a:
"scripts": {
"heroku-prebuild": "bash preinstall.sh",
"heroku-postbuild": "bash postinstall.sh"
}
He encontrado una alternativa a la respuesta de Michael, que retiene el requisito (IMO) favorable de mantener sus credenciales fuera del control de la fuente, sin requerir un buildpack personalizado. Esto surgió de la frustración de que el buildpack vinculado por Michael está bastante desactualizado.
La solución es configurar y desmontar el entorno SSH en las secuencias postinstall
comandos preinstall
y postinstall
npm, en lugar de en el buildpack.
Siga estas instrucciones:
- Cree dos scripts en su repositorio, llamémosles
preinstall.sh
ypostinstall.sh
. - Hazlos ejecutables (
chmod +x *.sh
). - Agregue lo siguiente a
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
- Agregue lo siguiente a
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
Agregue lo siguiente a su
package.json
:"scripts": { "preinstall": "bash preinstall.sh", "postinstall": "bash postinstall.sh" }
Genere un par de claves privadas / públicas utilizando
ssh-agent
.- Agregue la clave pública como una clave de implementación en Github.
- Crea una versión codificada en base64 de tu clave privada y
GIT_SSH_KEY
como la configuración de Heroku varGIT_SSH_KEY
. - Comprométase y envíe su aplicación a Github.
Cuando Heroku construye su aplicación, antes de que npm instale sus dependencias, se ejecuta el script preinstall.sh
. Esto crea un archivo de clave privada a partir de los contenidos descodificados de la variable de entorno GIT_SSH_KEY
, y crea un archivo de configuración SSH para indicarle a SSH que use este archivo cuando se conecte a github.com
. (Si se está conectando a Bitbucket, actualice la entrada de Host
en preinstall.sh
a bitbucket.org
). npm luego instala los módulos usando esta configuración SSH. Después de la instalación, la clave privada se elimina y la configuración se borra.
Esto le permite a Heroku desplegar sus módulos privados a través de SSH, mientras mantiene la clave privada fuera de la base del código. Si su clave privada se ve comprometida, ya que es solo la mitad de una clave de implementación, puede revocar la clave pública en GitHub y regenerar el par de claves.
Además, dado que las teclas de implementación de GitHub tienen permisos de lectura / escritura, si está alojando el módulo en una organización de GitHub, puede crear un equipo de solo lectura y asignarle un usuario de ''implementación''. El usuario de implementación se puede configurar con la mitad pública del par de llaves. Esto agrega una capa adicional de seguridad a su módulo.