Question

Does Heroku allow an app internally to git clone (e.g., via a simple bash script) a remote repository locally and push to some other remote that is available?

I am thinking of writing an automated (but manually triggered) hubot script.

To do this, on Heroku, you should be able to:

  1. Run commands (e.g., git)
  2. Save cloned repository in the filesystem

Thanks.

Update

Based on Benjamin’s answer, I tried as follows, but that doesn’t seem to persist files even between sessions. Any ideas?

$ heroku create
Creating obscure-river-7652... done, stack is cedar
http://obscure-river-7652.herokuapp.com/ | git@heroku.com:obscure-river-7652.git

$ heroku run --app obscure-river-7652 bash
Running `bash` attached to terminal... up, run.4427
    $ find .
    .
    $ mkdir -p foobar
    $ touch foobar/README 
    $ find .
    .
    ./foobar
    ./foobar/README
    $ exit

$ heroku run --app obscure-river-7652 bash
Running `bash` attached to terminal... up, run.5463
    $ find .
    .
Was it helpful?

Solution

Yes, that will work. Heroku has an ephemeral writable filesystem, which allows you to write data from a dyno. However, when you restart the dyno or start a new one, the data will be gone (because it is ephemeral). However, if you are pulling and pushing at the same time, it won't be a problem.

One thing that may be a problem is setting up your permissions. You will have to setup either your private keys or a username and password on Heroku if you want the dyno to be able to access a private repository.

One method would be to use GitHub deploy keys. Setup a deploy key for use on the Heroku app and set something like heroku config:set PRIVATE_KEY=ABCD123... with the private key. The deploy key will also have to be present on whatever server you are deploying to. This could be in your Heroku account, or in ~/.ssh/authorized_keys on a server.

Then, there are two methods for getting this key into your running Hubot instance.

Creating ~/.ssh/id_rsa with an initializer

Before your app runs, put the data from $PRIVATE_KEY into ~/.ssh/id_rsa with an initializer or some other startup script. This can probably be done with a custom Hubot plugin, and I will look into how that might be done.

Creating ~/.ssh/id_rsa at build time with a custom buildpack

For a more advanced setup, you can use a custom buildpack to copy the key into the ssh directory during compilation with the user-env-compile feature, the multi buildpack buildpack, and the inline buildpack.

Enable user-env-compile.

heroku labs:enable user-env-compile

Configure your app to use the multi buildpack.

heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git

Add the inline buildpack and your original buildpack to .buildpacks.

cat > .buildpacks << BUILDPACKS
https://github.com/kr/heroku-buildpack-inline.git
https://github.com/heroku/heroku-buildpack-nodejs.git
BUILDPACK

Finally, create the scripts for the custom buildpack.

In bin/release,

echo '--- {}'

In bin/detect

echo 'custom'

In bin/compile

mkdir ~/.ssh
chmod 700 ~/.ssh/
cat > ~/.ssh/id_rsa << KEY
-----BEGIN RSA PRIVATE KEY-----
$PRIVATE_KEY
-----END RSA PRIVATE KEY-----
KEY
chmod 400 ~/.ssh/id_rsa
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

What happens now, is that when your app gets pushed to Heroku, the multi buildpack will run the inline buildpack. The inline buildpack will run your custom buildpack from bin/{compile,detect,release}. This custom buildpack copies the $PRIVATE_KEY environment variable to ~/.ssh/id_rsa and generates the public key. $PRIVATE_KEY is available because the user-env-compile feature is turned on. Finally the multi buildpack runs the original Node.js buildpack, and everything should run smoothly.

Caveats

If you are using this buildpack method, updating your private key with heroku config:set PRIVATE_KEY=mynewkey, your app will be restarted, but not rebuilt. You will need to either push an empty commit, like so:

git commit -m "Rebuild private key." --allow-empty && git push heroku master

Or wait until your next deploy for Heroku to automatically rebuild the key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top