How to install private gems on heroku

January 05, 2011 18:22

Scenario: I have to setup a staging app on Heroku. Sounds pretty simple, should take an hour tops, right? Think again.

Mix in a gem from a private git repo and it gets messy. If the gem isn’t installed via version but with a commit ref you get even more fun.

Setup the app on Heroku as you normally would, then try to deploy. Everything looks good, until it tries to fetch the private gem. Then

git push heroku staging:master
-----> Heroku receiving push
-----> Rails app detected
-----> Detected Rails is not set to serve static_assets
       Installing rails3_serve_static_assets... done
-----> Gemfile detected, running Bundler version 1.0.3
       Unresolved dependencies detected; Installing...
...

<tries to install private gem>

Permission denied (publickey).
fatal: The remote end hung up unexpectedly

Hrm… Poke around the google some and find I’m not the only one. See references to an ~/.ssh/config that looks something like

Host heroku.com
  HostName heroku.com
  User git
  ForwardAgent yes
  IdentitiesOnly yes

Sounds reasonable. Nope, no luck. More time with google and it would seem that Heroku doesn’t pass your keys out the other side. Not sure if they have a specific reason for it or it’s just the default sshd_config.

Ok, that’s not going to work. Lets try dropping the gem in vendor/cache and see if that helps. Oh, there isn’t an actual gem to cache. Lets grab the one in bundler. Nope that wont work either.

Off to build the gem so I can place it in vendor/cache.

cd ../my_gem
rake build
cp pkg/my_gem-0.0.2.gem ../rails_app/vendor/cache
cd ../rails_app
bundle install

WTF!? Oh, it saw one gem in the cache dir, I must want them all in there, right?? No, no I don’t.

Ok, well let’s place the gem in the app in a place I can get to it with bundler but it wont randomly trigger some other unwanted behavior.

gem install ../my_gem/pkg/my_gem-0.0.2.gem
gem unpack my_gem -v 0.0.2 --target vendor/private_gems

Ok now I update my Gemfile to look like

gem 'my_gem',
  :path => 'vendor/private_gems/my_gem-0.0.2'

So far it seems happy.

Though I have seen some really strange issues with it randomly Throwing the Gemfile.lock - Heroku has a read-only filesystem error which would make perfect sense other than the fact that the error came from running heroku rake db:migrate right after a successful push.

Comments

Gravatar
Barnett January 21, 2011 01:35

Great tutorial about install private gems on heroku , they are very easy to understand. Thanks!

Gravatar
Wolfram Arnold January 20, 2012 19:30

Another option, as per Heroku tech support is to put the username and password into the github URL, like it’s done for Basic HTTP Auth. Details here: http://stackoverflow.com/a/8949955/459863

Gravatar
UnderpantsGnome January 24, 2012 17:07

@wolfram

That’s a good option for a project that isn’t shared. For a project with multiple developers that means you have to add another collaborator on the repo, because you aren’t going to want anybody’s real login details in your Gemfile.

Gravatar
Sean Corbett February 20, 2012 16:38

It’s a pain the support for this is not quite there with Heroku. I’ve added a comment to a thread in the heroku google group: http://groups.google.com/group/heroku/browse_thread/thread/8bd97706f3b87ee8?pli=1 (the comment is currently awaiting moderation)

I’m going to give gemfury a go, it looks like it’ll be easier than hosting my own git server or manually packaging and 20+ gems into my apps.

Gravatar
Michael Prendergast May 07, 2012 19:57

Thanks for this, it really helped.

For some reason though, I was getting the following error:

Could not find gem ‘interval_checker (>= 0) ruby’ in source at vendor/private_gems/interval_checker-1.0.0.
Source does not contain any versions of ‘interval_checker (>= 0) ruby’.

To fix this, I had to add the version number separately in the gemfile, as in:

gem 'my_gem', '0.0.2', :path => 'vendor/private_gems/my_gem-0.0.2'

Hopefully this helps somebody.

Thanks again,
Mike

Add a comment

Textile enabled (Reference)