How do I manage bundled gems in a capistrano deployment? - ruby-on-rails

Currently, I'm just running the following:
after 'deploy:update_code', 'deploy:bundle'
namespace :deploy do
task :bundle do
run "cd #{release_path} && bundle install --deployment --without development test staging"
end
end
Now this works fine, but the bundler ends up installing all the gems to vendor/gems every time. While I understand the merit in isolating the gems to each release (as opposed to using the shared folder, which (?) might result in errors on rollback and such), surely there is a better way to do this that doesn't take as much time to deploy and saves on disk space.

Things have changed after the release of bundler 1.0
You don't need to create a custom task from deploy.
just use require 'bundler/capistrano'
take a look at this http://blog.josephholsten.com/2010/09/deploying-with-bundler-and-capistrano/ for more details

Related

Having to type "bundle exec" before rake tasks now after Rails upgrade

I really like that Spring is included in the Rails standard Gemfile now. I have a new project I started from scratch where I can just type:
rake <my rake task>
and it's run under Spring so that the whole environment doesn't have to load again.
However, I recently upgraded a project from v3.2 to v4.2.3, and I get an error. It only works if I do:
bundle exec rake
How can I get this upgraded project to run under spring again?
It seems you have system wide and application specific gem sets that conflict each other. Simply remove system wide gems and use Bundler special feature. Bundler binstubs helps to avoid prepend bundle exec every time:
gem uninstall rake
bundle install --binstubs
./bin/rake
https://github.com/sstephenson/rbenv/wiki/Understanding-binstubs
Assuming the binstubs for a project are in the local bin/ directory,
you can even go a step further to add the directory to shell $PATH so
that rspec can be invoked without the bin/ prefix:
export PATH="./bin:$PATH"
rake

How to use bundle with local gems during Mina deployment of Rails app?

I'm deploying a Rails app with Mina mina:deploy which clones from a git repo and Bundler installs the gems.
# /config/deploy.rb
# ...
task :deploy => :environment do
deploy do
invoke :'git:clone'
invoke :'bundle:install'
# ...
end
end
However, unlike when I bundle install manually, mina is installing each gem anew. With a healthy number of gems, this takes roughly 10 minutes to complete. How can I deploy while pointing bundler to use any locally available (already installed) gems where possible?
I've also tried replacing invoke :'bundle:install' with queue! "bundle install --local" with no change in behavior.
For that you need to use a local copy of the gems that you have without checking rubygems so after installing gems you run bundle package to create a cache of the gems used and instead of running bundle install you should run bundle install --local to use only the cached copy of gems without checking the rubygems.com .

capistrano won't run bundle install

I'm using chef and capistrano to create a server and later deploy my code. As I'm new to capistrano I took a tutorial from here and made some minor changes in order to get it going for me.
Whatever I do, I just cant get a bundler install to run on the remote server. Because of that there is no rake and the process stops at the assets:precompile. A github repo containing the code.
Am I trying something that I shouldn't do?
I fixed it with an additional task that explicitly runs bundle install. After that I still got an exception: stdout: Nothing written. I needed to add , raise_on_non_zero_exit: false
to be able to continue. Is anybody has a real test() to see if bundle install ran successfully I would be interested.
namespace :bundle do
desc "run bundle install and ensure all gem requirements are met"
task :install do
on roles(:app) do
execute "cd #{release_path} && RAILS_ENV=#{fetch(:stage)} bundle install --without=test", raise_on_non_zero_exit: false
end
end
end

How to deploy a custom Gem using capistrano?

I'm new to RoR. My gem does some background processing and loads a thin server so it can be checked from time to time. I need to put this on my web server using Capistrano.
Do people normally deploy gems to their servers or should the app be written in some other way?
Also is Capistrano the correct way to deploy gems?
Have you checked out Bundler before? That works very well with capistrano deployments and you can use to package your gems with your app on deployments.
Or you can use the gem Jeweler : https://github.com/technicalpickles/jeweler
I found out deploying a custom Gem is no different to any other project type. I just needed to add a new Capistrano task to my deploy.rb file so that the gem could get installed after the files get downloaded onto the server by Capsitrano. This is all I had to do.
desc "Install this gem"
task :setup_install, roles: :app do
run "cd #{release_path} && gem build zoe.gemspec"
run "cd #{release_path} && gem install YOUR-GEM-NAME.gem --quiet"
end
after "deploy:finalize_update", "deploy:setup_install"
desc "Uninstall this gem"
task :setup_uninstall, roles: :app do
run "gem uninstall -x YOUR-GEM-NAME"
end
before "deploy:setup_install", "deploy:setup_uninstall"

Can't get bundle exec to work in production

I've installed my gems in production with:
cd /app/releases/current && bundle install --gemfile /app/releases/current/Gemfile --path /app/shared/bundle --deployment --quiet --without development test
I can't bundle exec any of my gems (except rake and gem):
$ bundle exec whenever
bundler: command not found: whenever
Install missing gem executables with `bundle install`
The gems are correctly installed in /app/shared/bundle:
$ cd /app/shared
$ find . -name whenever
./bundle/ruby/1.9.1/gems/whenever-0.6.8/bin/whenever
./bundle/ruby/1.9.1/gems/whenever-0.6.8/lib/whenever
My (generated) bundle config (in /app/current/.bundle/config) is:
---
BUNDLE_FROZEN: "1"
BUNDLE_PATH: /app/shared/bundle
BUNDLE_DISABLE_SHARED_GEMS: "1"
BUNDLE_WITHOUT: development:test
I'm running ruby 1.9.2p290, manually installed to /usr/local/bin.
Do I have to bundle install my gems with the --binstubs option? Why wouldn't bundle exec be searching the stored BUNDLE_PATH?
Using Capistrano and Rails and using deploy.rb as deployer file.
I realized that changing the order where appears require "whenever/capistrano" really matters. I put that at almost the last line:
In deploy.rb:
#first lines:
set :rvm_ruby_string, "1.9.3"
set :rvm_type, :user
set :whenever_command, "bundle exec whenever"
# others...
# last lines
require 'rvm/capistrano'
require 'bundler/capistrano'
require "whenever/capistrano"
after "deploy:update_code", "customs:config"
after "deploy:create_symlink","deploy:create_symlink"
after "deploy", "deploy:cleanup"
load 'deploy/assets'
# end
I had this problem and had the requires in the correct order, i.e.
require 'rvm/capistrano'
require 'bundler/capistrano'
require 'whenever/capistrano'
It still wanted to run the crontab update before bundle:install. The solution was to update my local bundler with
gem update bundler
After that it started working again. Not sure exactly what changed between versions that broke all of this.
Check where your bundle:install is being set, and try moving it above require 'whenever/capistrano' in your deploy.rb file.
It seems like this was triggered when I did a bundle update that increased the whenever gem version in my Gemfile.lock.
It looks like whenever tries to run it's chrontab update before my deploy file runs bundle:install
from https://github.com/javan/whenever/blob/master/lib/whenever/capistrano.rb
before "deploy:finalize_update", "whenever:update_crontab"
And my deploy.rb had
after 'deploy:finalize_update', 'bundle:install'
Like everyone else in this thread, I tried a few things and I'm not sure this is what fixed it for me, but changing bundle install to before deploy:finalize_update, and also setting it as "before" above requiring 'whenever/capistrano' seems like it's the likely fix in my scenario.
I think when whenever gem is not in your Gemfile, or it's in the test or development section of your Gemfile
I changed the --path from /app/shared/bundle to vendor/bundle, which made it work.
This seemed wrong to me, so I removed /app/shared/bundle and vendor/bundle, and ran bundle install again to /app/shared/bundle.
This clean bundle install fixed the problem. I have no idea why!
If anyone has an explanation for this, I'd love to mark you as the accepted answer. But this fixed the problem for me.
Probably different issues cause the same error message. For me, I had to update capistrano gem after having updated whenever gem to get roles support. bundle exec whenever had worked prior to my upgrade of whenever.
Using the brightbox deployment gem, which handles bundler etc for me (by magic, in some other recipes) I found this works:
Replace
require "whenever/capistrano"
with the contents of https://github.com/javan/whenever/blob/master/lib/whenever/capistrano/v2/hooks.rb
then modify it to load after bundler:install finishes (you may or may not have that task, I don't know if it's standard)
# require "whenever/capistrano"
# hacked whenever/lib/whenever/capistrano/v2/hooks.rb below to work with brightbox bundler installation
require "whenever/capistrano/v2/recipes"
# Write the new cron jobs near the end.
after "bundler:install", "whenever:update_crontab"
# If anything goes wrong, undo.
after "deploy:rollback", "whenever:update_crontab"

Resources