Get Unicorn to only access vendor/cache gems - ruby-on-rails

It seems when I run bundle package then bundle install --local then I run unicorn_rails, unicorn is still accessing system gems. I keep getting :
You have already activated rack 1.5.2, but your Gemfile requires rack
1.2.8. Using bundle exec may solve this.
And it shouldn't because rack 1.2.8 is in the vendor/cache.
bundle exec wont work because it seems to be a resource hog and the whole point of bundle package is avoid this whole mess in the first place.
So how do I get unicorn to get bundle environment to only use the vendor/cache gems?

bundle install --local takes gems in vendor/local and installs them using whatever your default gem command does. By default, that is a system-wide install. If you're using RVM or something else, it'll be in your current RVM gemset.
If you're installing in production, and you want to limit the app to your gems from vendor/local, you want to do bundle install --deployment. This will install the gems into vendor/bundle and set Bundler up to use those gems (and only those gems, not the system ones). If the gems aren't in vendor/local, it will download them. It won't update your Gemfile.lock, and best practice is to keep all your gems in vendor/cache up to date to prevent it from even trying to download gems.
You don't need to use bundle exec unless you're running a binary from one of the gems. If you're running rails server and having this problem, the reason is that the rails command is running from the shell's $PATH. It's presumably a different version of Rails than the one you'd like to use.
If that's the case, your options are to track down the path to the version of rails you want and run it explicitly, to use bundle exec, or to run bundle install --binstubs --deployment and add that bin directory to your PATH. I haven't noticed any overhead from bundle exec, but if you're concerned about that and still want to scope everything to your bundle, then use --binstubs (this is how Heroku does it, by the way).

Related

Why is "install" run twice?

I'm going through Micharl Hartl's well known Rails tutorial, and this piece is confusing me. Every time a new app is set up, these commands are run:
$ bundle install --without production
$ bundle update
$ bundle install
I don't really get why install is being run twice. What is the effect of these three commands run in this sequence?
You should not have to run bundle install twice as bundle update will also install all of your gems (as well as updating them to their most current version). I have not read the tutorial you mentioned but perhaps the purpose of the second install is to install all of the gems, including those reserved for production.
Your second question, what is the effect of these three commands:
bundle install --without production
Inspect the gemfile, ignoring gems that are reserved for production
Resolve all dependencies
Install all gems and dependent gems
Save the exact version of each gem to Gemfile.lock
bundle update
Inspect the gemfile
Resolve all dependencies from scratch using the newest version of each gem and completely ignoring Gemfile.lock
Install all gems and dependent gems
Save the exact version of each gem to Gemfile.lock
bundle install
Because this is the first run of the production gems, inspect the gemfile and resolve dependencies of the production gems
Use Gemfile.lock for exact versions of all other gems to be installed
Install all gems and dependent gems
Save the exact version of each gem to Gemfile.lock
Hoped this helped, for more detailed info about the two commands check out this and this.
$ bundle install --without production prevents bundler from installing any of the production gems. It also gets saved in your local repository and you don't have to run it more than once. Any subsequent run of bundle install will include --without production.
bundle install installs only the missing gems from your Gemfile, while bundle update updates/installs every single gem to the latest version as specified in the GemFile..

Gem list contains multiple dependencies to a certain gem

I had unicorn 4.5.0 and after I did bundle update, I observe different versions of the same gem even though I wanted to use the latest version.
unicorn (4.6.1, 4.5.0)
How do I instruct the bundler to just keep the latest version.
As far as I can see you cannot instruct bundler to keep only the latest version when updating. You can delete all the old versions of all gems in one go:
bundle exec gem cleanup
(Reference)
You can instruct bundler to just use one version by putting that version in the gem file. Sometimes, I have had conflicts with rake, even though I did not explicitly have rake in my Gemfile, so I had to put the rake version that would be usable by all the other gems at the top of my Gemfile.
If your issue is that you used to use unicorn 4.5.0, and now it has installed unicorn 4.6.1 in you local gem source, you can tell gem to uninstall the version you no longer need.
gem uninstall unicorn --version 4.5.0
If you did a bundle --deployment and populated the vendor/bundle directory, and that is where you want to remove the gem from, then I usually just delete the gem directory, however, I think you can run bundle with --path, like the following:
bundle --deployment --path vendor/bundle
gem uninstall unicorn --version 4.5.0
When you run bundler, it remembers the settings. I painfully discovered this regarding the --without switch. The --path setting will tell gem to use the local vendor/bundle directory as your local gem source. Remember to set the path back by running bundle again.

Bundler is not "bundling" sqlite3

I have a very recurrent problem here. (it happens literally all the time). I have found ways to go around it but i really would appreciate a solution for this problem:
Here is how it goes:
At my development machine, i have in my gem file a line like this:
gem "sqlite3-ruby", :require => "sqlite3"
what happens is that, when i bundle install --no-deployment, it goes alright:
Using sqlite3 (1.3.5)
Using sqlite3-ruby (1.3.3)
Updating .gem files in vendor/cache
Your bundle is complete! It was installed into ./vendor/bundle
But then, in the deployment, running bundle install --deployment, i get:
Using sqlite3-ruby (1.3.3)
Updating .gem files in vendor/cache
Your bundle is complete! It was installed into ./vendor/bundle
... which causes require errors that makes the application crash.. Then, what i do is bundle install --no-deployment at the deployment machine. Then i run again bundle install --deployment and then, magically:
Using sqlite3 (1.3.5)
Using sqlite3-ruby (1.3.3)
Updating .gem files in vendor/cache
And then the application runs fine.
So, what i most basically want is that bundler recognizes the sqlite3 dependency on sqlite3 gem
But then, in the development, running bundle install --deployment, i get:
Okay, this is the first suspicious thing. Why would you run --deployment in development?
You generally don't want to do that. If you're switching all the time between "--deployment" and "--no-deployment" on the same machine, it's easy to get things confused, yes.
Running "bundle install --deployment" will save something in the .bundle/config file in your project, that tells bundler "from here on out, only install these certain gems". "--no-deployment" removes that again, in case you made a mistake or need to hack around. But in general, you shouldn't need to and don't want to always be switching back and forth. Run --deployment on your production/deployment machine, don't run it on your development machine. You don't ever need to run --no-deployment unless you made a mistake and didn't mean --deployment
At this point, I'd rm -rf .bundle (it's okay, it'll just remove all the things bundler 'remembers' about what you want to do, like --deployment), and start over with bundle install.
If there's some reason this doesn't work, then that's the question.
From the line Updating .gem files in vendor/cache, I suspect at some point you also ran bundle package, which is another thing that's "remembered" in the .bundle/config thing, and is also probably interacting with your other commands oddly and doing things you don't expect. Removing your .bundle/config will get rid of that remembered setting too. (you may also need to delete your ./vendor/cache directory contents)
Just run bundle install unless you have a reason you understand for needing package, and understand what it does. Or it'll confuse you.

Passenger 3 with Rails 3 doesn't load gems from vendor/

I've setup a new environment with Ruby 1.9.2 and Passenger 3. A Rails 3 app is deployed with Capistrano. RAILS_ENV is set to staging.
When trying to boot the application, Passenger complains about a missing gem. Running
bundle --deployment
installs gems to RAILS_ROOT/vendor, but doesn't solve the error.
If I install the missing gem as a system gem (eg. sudo gem install), the error disappears but now the next gem in the Gemfile is reported as missing.
I could solve this by installing my gems to the system, but I'd like to understand why installing them to the vendor directory isn't working. My understanding is that the idea of bundler is to avoid having to keep all gems installed to the system.
I have RAILS_ROOT/.bundle/config set to:
BUNDLE_FROZEN: "1"
BUNDLE_PATH: vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: "1"
Ideally, gems should remain in a consistent location to avoid them being reinstalled every deploy. Therefore, try removing BUNDLE_PATH from your config (default location is ~/.bundle).
I'm not sure what bundle --deployment does (I couldn't see mention of this in the docs). I use something like this command in my deploy scripts:
after :'deploy:update_code' do
run "cd #{release_path} && bundle install --without test cucumber development"
end

Extract bundled gems into system gems

This might sound as a strange thing to do. Is there a bundler way to extract the bundled gems (from a Gemfile or from .bundle) and install them as system gems outside of the bundler context?
Something like bundle package, but instead of caching them in vendor/cache, installs them as system gems.
The new bundler does this by default
When you run bundle install your gems are installed to your BUNDLE_PATH (which defaults to ~/.bundle.
You can pass an argument specifying where you want to install your gems to; bundle install /usr/local/lib/bundle. From the user manual, "Further bundle commands or calls to Bundler.setup or Bundler.require will remember this location".
Of course, you'll need to use sudo to install to a system directory.
Is that what you're after?

Resources