If you have the vendor/bundle
directory in your project then at some point you must have run the bundle
command with the --path vendor/bundle
argument. This will load the files for all your project's gems (listed in Gemfile
) into the vendor/bundle
directory in your local project rather than to a system gem location. You would do this to completely isolate a project's gems from any other project.
Bundler is good at resolving all dependencies so it isn't necessary to use the --path
but some people choose to do so as they wish to keep their gems separate and organised with their project. It also means that bundler on your local machine is set up the same way that Heroku uses bundler.
With this option you are still downloading all gems from the rubygems
servers every time you run the bundle
command.
bundle package
takes it a step further and actually downloads the original gem files from rubygems
and caches them into the vendor/cache
directory. This means that you no longer need a connection to rubygems
to run the bundle command as it will use the packaged files as the source. If you need to update a gem version then it will need to connect to rubygems
to collect the new version the first time it is requested. Using bundle package
will of course require additional disc space which may or may not be an issue depending on the situation. It would also increase deploy time and bandwidth requirements every time you pushed to Heroku.
Heroku runs the bundle
command every time you git push
, reading your Gemfile.lock
and installing the gems required for the application to work. By default the --path vendor/bundle
option is used. This is so that each application has a set of gem files separate from all other apps on Heroku. If you have the vendor/bundle
directory in your source control and you push it to Heroku then you can see that there is the potential for significant conflict as it then attempts to load gems into vendor/bundle
directory which already exists. If it is pushed then Heroku removes the vendor/bundle
directory before it runs bundle install
to remove these potential conflicts. If this is the case then you will be wasting deploy time and bandwidth by leaving vendor/bundle
under version control, it's better to add it to your .gitignore
.
If you want complete control over your gems on Heroku then use the bundle package
command and make sure that the vendor/cache
directory is under source control. When Heroku runs bundle install
it will use the contents of vendor/cache
as the gem source rather than using rubygems
. Whether this is useful or not will be a matter of personal preference, the type of app that you are building and how often you update your gems. The Ryan McGeary post suggests that using bundle package
is useful in case an old gem becomes unavailable at some point in the future. This would appear to be a bigger issue to projects/apps which are not regularly kept up to date.
From my perspective, I generally use --path vendor/bundle
to keep my local setup as close as possible to Heroku's. I put vendor/bundle
into my project's .gitignore
file, and I don't package gems, as my projects are updated relatively regularly.
Rails has a very limited .gitignore
file. You are effectively expected to build up what you need yourself, which is why vendor/bundle
is not included by default.
I assume that Heroku means bundle package
when they say bundle pack
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…