Capistrano 3: bundler not recognized when running custom shell command - ruby-on-rails-3
I'm having an issue implementing Capistrano deployment with jruby on RVM. I'm using PUMA as app server and that requires me to add capistrano3-puma in my Gemfile.
All in all, everything seems to work perfectly, my server's code got up-to-date fine from the git repo, and had the previous version of code archived nicely.
Except, every time I try to run shell command from Capistrano task,
such as, "bundle exec pumactl -F config/puma.rb start", for example, Capistrano can't seem to recognise bundle command.
My real case example is shown as below, when I run the above mentioned command in an overrided deploy:start method it return an error "bundle: command not found". I already tested the same command works fine, when I log on to the server via SSH and launch it from the app folder directly.
jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on OpenJDK 64-Bit Server VM 1.7.0_65-b32 +jit [linux-amd64]
** Invoke deploy:start (first_time)
** Execute deploy:start
INFO[fc57a7d8] Running /usr/bin/env cd /var/appname/current && bundle exec pumactl -F config/puma.rb start on 192.168.2.6
DEBUG[fc57a7d8] Command: cd /var/appname/current && bundle exec pumactl -F config/puma.rb start
bind address:
port: 22
host: 192.168.2.6
options: {:auth_methods=>["none", "publickey", "password", "keyboard-interactive"], :send_env=>[/^LANG$/, /^LC_.*$/], :user=>"root
", :forward_agent=>true, :logger=>#<Logger:0x14c7b324 #logdev=#<Logger::LogDevice:0x42c20b24 #filename=nil, #shift_age=nil, #dev=#
<IO:fd 2>, #mutex=#<Logger::LogDevice::LogDeviceMutex:0x51698ab9 #mon_count=0, #mon_mutex=#<Mutex:0x6812a170>, #mon_owner=nil>, #s
hift_size=nil>, #formatter=nil, #progname=nil, #default_formatter=#<Logger::Formatter:0x1f24f571 #datetime_format=nil>, #level=4>}
DEBUG[fc57a7d8] ***bash: bundle: command not found***
cap aborted!
Exception while executing on host 192.168.2.6: cd /var/appname/current && bundle exec pumactl -F config/puma.rb start exi
t status: 127
cd /var/appname/current && bundle exec pumactl -F config/puma.rb start stdout: Nothing written
cd /var/appname/current && bundle exec pumactl -F config/puma.rb start stderr: Nothing written
/Users/dev/.rvm/gems/jruby-1.7.16.1#rails3.2.8/gems/sshkit-1.5.1/lib/sshkit/command.rb:97:in `exit_status='
/Users/dev/.rvm/gems/jruby-1.7.16.1#rails3.2.8/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:148:in `_execute'
org/jruby/RubyProc.java:271:in `call'
here is my Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Deploy.rb
server '192.168.2.6', port: 22, roles: [:app], primary: true
set :repo_url, 'git#bitbucket.org:username/appname.git'
set :application, 'appname'
set :user, 'username'
set :puma_threads, [4, 16]
set :puma_workers, 0
set :shared_children, []
set :default_env, { rvm_bin_path: '~/.rvm/bin' }
set :default_shell, '/bin/bash -l'
set :pty, true
set :use_sudo, false
set :stage, :staging
set :deploy_via, :remote_cache
set :deploy_to, "/var/#{fetch(:application)}"
set :linked_dirs, %w{tmp/pids tmp/sockets log}
set :puma_bind, "unix:///#{fetch(:deploy_to)}/tmp/sockets/puma.sock"
set :puma_state, "#{fetch(:deploy_to)}/tmp/pids/puma.state"
set :puma_pid, "#{fetch(:deploy_to)}/tmp/pids/puma.pid"
set :puma_access_log, "#{fetch(:deploy_to)}/log/puma.error.log"
set :puma_error_log, "#{fetch(:deploy_to)}/log/puma.access.log"
set :ssh_options, { forward_agent: true, user: fetch(:user) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, false # Change to true if using ActiveRecord
namespace :puma do
desc 'Create Directories for Puma Pids and Socket'
task :make_dirs do
on roles(:app) do
execute "mkdir #{shared_path}/tmp/sockets -p"
execute "mkdir #{shared_path}/tmp/pids -p"
end
end
before :start, :make_dirs
end
namespace :deploy do
desc "Make sure local git is in sync with remote."
task :check_revision do
on roles(:app) do
unless `git rev-parse HEAD` == `git rev-parse origin/master`
puts "WARNING: HEAD is not the same as origin/master"
puts "Run `git push` to sync changes."
exit
end
end
end
desc 'Initial Deploy'
task :initial do
on roles(:app) do
before 'deploy:restart', 'puma:start'
invoke 'deploy'
end
end
desc "Start the application"
task :start do
on "root#192.168.2.6", in: :sequence, wait: 5 do
with :rails_env => fetch(:rails_env) do
execute "cd #{current_path} && /bin/bash -l bundle exec pumactl -F config/puma.rb start"
end
end
end
before :starting, :check_revision
after :finishing, :compile_assets
after :finishing, :cleanup
after :finishing, :restart
end
staging.rb
set :stage, :staging
set :branch, 'master'
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.2.8'
gem 'rubyzip', '< 1.0.0'
gem 'roo','1.12.1'
gem 'jdbc-mysql', platform: :jruby
gem 'activerecord-jdbcmysql-adapter', platform: :jruby
gem 'jquery-rails', '2.1.2'
gem 'haml', '3.1.7'
gem 'puma'
gem 'devise', '2.1.2'
gem 'devise-async', '0.5.0'
gem 'cancan', '1.6.8'
gem 'simple_form', '2.0.4'
gem 'cocoon', '1.1.1'
gem 'inherited_resources', '1.3.1'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.9'
gem 'mechanize', '2.5.1'
gem 'delayed_job', '3.0.4'
gem 'paperclip', '3.4.0'
gem 'spreadsheet', '0.6.4.1'
gem 'geocoder', '1.1.6'
gem 'whenever', '0.8.2'
gem 'american_date', '1.0.0'
gem 'money','5.1.1'
gem 'rets','0.5.1'
gem 'haversine','0.3.0'
group :assets do
gem 'stylus', '0.7.1'
gem 'coffee-rails', '3.2.2'
gem 'uglifier', '1.3.0'
end
group :development do
gem 'capistrano', require: false
gem 'capistrano-rvm', require: false
gem 'capistrano-rails', require: false
gem 'capistrano-bundler', require: true
gem 'capistrano3-puma', github: 'seuros/capistrano-puma', require: false
end
any advice to help me resolve the problem would be very, very much appreciated.
UPDATED
after editing the code as rubish suggested,
now instead I issue the command like this => execute "cd #{current_path} && /bin/bash -l bundle exec pumactl -F config/puma.rb start"
now, it get to and is complaining about bundler under global rvm path. The exact new error looks like the following.
DEBUG[df47d6e1] Finished in 0.463 seconds with exit status 0 (successful).
jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on OpenJDK 64-Bit Server VM 1.7.0_65-b32 +jit [linux-amd64]
** Invoke deploy:start (first_time)
** Execute deploy:start
INFO[93744fc5] Running /usr/bin/env cd /var/appname/current && /bin/bash -l bundle exec pumactl -F config/puma.rb start on
192.168.2.6
DEBUG[93744fc5] Command: cd /var/appname/current && /bin/bash -l bundle exec pumactl -F config/puma.rb start
bind address:
port: 22
host: 192.168.2.6
options: {:auth_methods=>["none", "publickey", "password", "keyboard-interactive"], :send_env=>[/^LANG$/, /^LC_.*$/], :user=>"root
", :forward_agent=>true, :logger=>#<Logger:0x4c860e93 #logdev=#<Logger::LogDevice:0x7526fc24 #filename=nil, #shift_age=nil, #dev=#
<IO:fd 2>, #mutex=#<Logger::LogDevice::LogDeviceMutex:0x5273db92 #mon_count=0, #mon_mutex=#<Mutex:0x34547888>, #mon_owner=nil>, #s
hift_size=nil>, #formatter=nil, #progname=nil, #default_formatter=#<Logger::Formatter:0x15b5438f #datetime_format=nil>, #level=4>}
DEBUG[93744fc5] /usr/local/rvm/gems/jruby-1.7.16.1#global/bin/bundle: line 9: require: command not found
DEBUG[93744fc5] /usr/local/rvm/gems/jruby-1.7.16.1#global/bin/bundle: line 11: version: command not found
DEBUG[93744fc5] /usr/local/rvm/gems/jruby-1.7.16.1#global/bin/bundle: bundle: line 15: syntax error near unexpected token
`('
DEBUG[93744fc5] /usr/local/rvm/gems/jruby-1.7.16.1#global/bin/bundle: bundle: line 15: ` str = str.dup.force_encoding("BI
NARY") if str.respond_to? :force_encoding'
cap aborted!
Exception while executing on host 192.168.2.6: cd /var/appname/current && /bin/bash -l bundle exec pumactl -F config/puma.
rb start exit status: 2
cd /var/appname/current && /bin/bash -l bundle exec pumactl -F config/puma.rb start stdout: Nothing written
cd /var/appname/current && /bin/bash -l bundle exec pumactl -F config/puma.rb start stderr: Nothing written
Generally RVM is initialized only in a login shell, so capistrano commands are unaware of RVM. Simply change your shell command to fix this:
# play nice with rvm
set :default_shell, '/bin/bash -l'
So you're pretty much hitting some of the same issues I did when I made my RoR + JRuby + Puma + RVM app. I don't remember all the details but there are a few things that you need to do
1 - I had to use capistrano3-puma from git that was not broken:
gem 'capistrano3-puma', github: 'seuros/capistrano-puma'
2 - Include rails env + path on rake tasks:
on roles(:db), in: :sequence, wait: 3 do
within current_path do
with :rails_env => fetch(:rails_env) do
rake "some:task"
end
end
end
3 - Finally - and this is the real messed up part since Puma doesn't read~/.bashrc to load RVM paths:
Put the loading of RVM paths in ~/.bash_profile also
There are a number of other things I had to do to get everything working but this should be the big stuff that's not implementation-specific. Also, don't forget to turn Puma into a service or you will have downtime.
Try adding the following in your config files(staging.rb, deploy.rb)
set :rvm_map_bins, fetch(:rvm_map_bins).to_a.concat(%w{ puma pumactl })
capistrano-puma gem doesn't always map its bundler with rvm it seems.
Related
Why capistrano check non existence of rbenv directory?
I get following message when I run cap production deploy in capistrano 3. DEBUG [5021b4ce] Running /usr/bin/env [ ! -d /usr/local/rbenv/versions/2.0.0-p451 ] on example.com DEBUG [5021b4ce] Command: [ ! -d /usr/local/rbenv/versions/2.0.0-p451 ] DEBUG [5021b4ce] Finished in 0.853 seconds with exit status 1 (failed). This is rbenv part in config/deploy.rb. set :rbenv_type, :system # or :user, depends on your rbenv setup set :rbenv_ruby, '2.0.0-p451' set :rbenv_path, '/usr/local/rbenv' set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec" set :rbenv_map_bins, %w{rake gem bundle ruby rails} set :rbenv_roles, :all # default value I thought Capistrano should check existence of rbenv directory. Why the command is [ ! -d #{rbenv_dir}], instead of [ -d #{rbenv_dir}]?
How to debug RVM setup from Chef and Vagrant?
I got RVM setup with Chef-solo on a Vagrant VM just fine, however I am confused on why bundler can not be found in the rails project. So, after provisioning I see: Last login: Thu Oct 4 15:23:58 2012 from 10.0.2.2 vagrant#vm:~$ ruby -v ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux] vagrant#vm:~$ gem list *** LOCAL GEMS *** bigdecimal (1.1.0) bundler (1.3.2) daemon_controller (1.1.1) fastthread (1.0.7) io-console (0.3) json (1.5.4) minitest (2.5.1) passenger (3.0.18) rack (1.5.2) rake (10.0.3, 0.9.2.2) rdoc (3.9.4) rubygems-bundler (1.1.1) rvm (1.11.3.6) Going to the project directory I see: vagrant#vm:~$ cd /www/vm/rails/current/ ============================================================================== = NOTICE = ============================================================================== = RVM has encountered a new or modified .rvmrc file in the current directory = = This is a shell script and therefore may contain any shell commands. = = = = Examine the contents of this file carefully to be sure the contents are = = safe before trusting it! ( Choose v[iew] below to view the contents ) = ============================================================================== Do you wish to trust this .rvmrc file? (/www/vm/rails/current/.rvmrc) y[es], n[o], v[iew], c[ancel]> y mkdir: cannot create directory `/usr/local/rvm/gems/ruby-1.9.3-p327#vm': Permission denied gemset vm is not existing, creating. mkdir: cannot create directory `/usr/local/rvm/gems/ruby-1.9.3-p327#vm': Permission denied mkdir: cannot create directory `/usr/local/rvm/gems/ruby-1.9.3-p327#vm': Permission denied But now, bundle can not be found anymore, and I also have problems to activate RVM... any ideas how to debug this? $ rvm use ruby-1.9.3-p327 Please note that `rvm gem ...` was removed, try `gem ` or `rvm all do gem ` instead. ( see: 'rvm usage' ) PS my node json is basically this: https://github.com/mulderp/chef-rails-stack
For debugging I use https://github.com/mpapis/rvm-binary/blob/master/cookbooks/binary/recipes/default.rb#L11 : class Chef::Resource::Script def log_code command if Chef::Config[:log_level] == :debug code "{ #{command}; _ret=$?; echo \"Exit status was $_ret.\"; exit $_ret; } 2>&1 | tee /var/log/#{#command.to_s.gsub(/ /,"_")}.log; exit ${PIPESTATUS[0]}" else code command end end end and then instead of code use log_code, it will save logs in /var/log/#{#command.to_s.gsub(/ /,"_")}.log as for easy integration of RVM with Chef check https://gist.github.com/sevos/5076747 : deploy_user = node[:deploy][:user] deploy_user_home = File.join('/', 'home', deploy_user) rvm_version = "head" execute "install_rvm_for_deploy_user" do user deploy_user command "curl -L https://get.rvm.io | bash -s #{rvm_version}" environment "HOME" => deploy_user_home creates "#{deploy_user_home}/.rvm" end node['buildpack']['ruby_versions'].each do |ruby_version| execute "install_rvm_ruby_#{ruby_version}" do user deploy_user environment "HOME" => deploy_user_home command "#{deploy_user_home}/.rvm/bin/rvm install #{ruby_version} --autolibs=3" end end file "#{deploy_user_home}/.rvmrc" do content 'export rvm_trust_rvmrcs_flag=1' owner deploy_user mode 0644 end
restart sunspot solr when make a deploy with capistrano in rails 3.1
I have a project rails 3.1 in production environment. This is my deploy.rb now: $:.unshift(File.expand_path('./lib', ENV['rvm_path'])) # Add RVM's lib directory to the load pathe require "rvm/capistrano" # Load RVM's capistrano plugin. require "bundler/capistrano" set :rvm_ruby_string, 'ruby-1.9.2-p318#global' set :rvm_type, :user set :application, "domain.com" set :user, 'user' #set :repository, "#{user}#ip.ip.ip.ip:~/app" set :repository, "ssh://git#bitbucket.org/user/app.git" set :keep_releases, 3 set :scm, :git set :use_sudo, false set :deploy_to, "~/#{application}" #set :deploy_via, :copy set :unicorn_conf, "#{deploy_to}/current/config/unicorn.rb" set :unicorn_pid, "#{deploy_to}/shared/pids/unicorn.pid" set :deploy_via, :remote_cache ssh_options[:forward_agent] = true default_run_options[:pty] = true role :web, "ip.ip.ip.ip" # Your HTTP server, Apache/etc role :app, "ip.ip.ip.ip" # This may be the same as your `Web` server role :db, "ip.ip.ip.ip", :primary => true # This is where Rails migrations will run namespace :deploy do task :restart do run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -USR2 `cat #{unicorn_pid}`; else cd #{deploy_to}/current && bundle exec unicorn -c #{unicorn_conf} -E #{rails_env} -D; fi" end task :start do run "bundle exec unicorn -c #{unicorn_conf} -E #{rails_env} -D" end task :stop do run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -QUIT ` cat #{unicorn_pid}`; fi" end end load 'deploy/assets' after "deploy:restart", "deploy:cleanup" I want make these tasks in capistrano. Now I perform these tasks manually: 1º I kill sunspot solr pid with: a) Find the pid with ps aux | grep 'solr' b) Kill pid with kill pid_number 2º Remove index solr in production environment if exist with: a) rm -r solr/data/production/index 3º turn on sunspot solr with: a) RAILS_ENV=production rake sunspot:solr:start 4º Reindex models with: a) RAILS_ENV=production rake sunspot:mongo:reindex My question is: How can I add these tasks to my deploy.rb? Thank you!
This might be a good starting point: namespace :solr do task :reindex do run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} sunspot:solr:reindex" end end You can just call the rake sunspot:solr:stop instead of kill? I'm not sure you need to remove the index if you are going to do a reindex...
task :stop_solr do begin run("cd #{deploy_to}/current && /usr/bin/env rake sunspot:solr:stop RAILS_ENV=#{rails_env}") rescue Exception => error puts "***Unable to stop Solr with error: #{error}" puts "***Solr may have not been started. Continuing anyway.***" end end #restart and reindex any newly added full search fields: task :restart_solr do begin run("cd #{release_path} && /usr/bin/env rake sunspot:solr:start RAILS_ENV=#{rails_env}") rescue Exception => error puts "***Unable to start Solr with error: #{error}." puts "***Continuing anyway.***" end end task :reindex_solr do begin run("cd #{release_path} && /usr/bin/env rake sunspot:reindex RAILS_ENV=#{rails_env}") rescue Exception => error puts "***Unable to reindex Solr with error: #{error}" puts "***Continuing anyway.***" end end Also, as I mentioned in my comment to Kris's answer, you'll have issues if you clean up old Capistrano directories, unless you kill the SOLR process and force it to point to new index files. One way to avoid this scenario is to set up SOLR in a shared directory and reset the symlink during deployment.
rake aborted! no such file to load -- bundler/setup
I run a rake task every night via cron (as root), when it runs it gives the error: rake aborted! no such file to load -- bundler/setup which I get in an email When I run it manually (as root), it runs just fine. I am running rvm if that helps. I am not really sure what to add to help, but here are a few things. # ruby -v ruby 1.9.2p180 (2011-02-18 revision 30909) [i686-linux] # rails -v Rails 3.0.9 # gem -v 1.8.5
try to set up your cron task like this * * * * * /bin/bash -l -c 'rake blah:blah'
Deploying Ruby on rails on Deamhost fails
I'm trying to deploy a simple Ruby on Rails app to dreamhost but I'm getting an error related to the bundle command. Here is the error: servers: ["bullseye.dreamhost.com"] [bullseye.dreamhost.com] executing command command finished * executing "find /home/USER-NAME/MY-DOMAIN/releases/20110123014150/public/images /home/USER-NAME/MY-DOMAIN/releases/20110123014150/public/stylesheets /home/USER-NAME/MY-DOMAIN/releases/20110123014150/public/javascripts -exec touch -t 201101230141.52 {} ';'; true" servers: ["bullseye.dreamhost.com"] [bullseye.dreamhost.com] executing command command finished triggering after callbacks for `deploy:update_code' * executing `bundle:install' * executing "ls -xt /home/USER-NAME/MY-DOMAIN/releases" servers: ["bullseye.dreamhost.com"] [bullseye.dreamhost.com] executing command command finished * executing "bundle install --gemfile /home/USER-NAME/MY-DOMAIN/releases/20110123014150/Gemfile --path /home/USER-NAME/MY-DOMAIN/shared/bundle --deployment --quiet --without development test" servers: ["bullseye.dreamhost.com"] [bullseye.dreamhost.com] executing command *** [err :: bullseye.dreamhost.com] sh: bundle: command not found command finished *** [deploy:update_code] rolling back * executing "rm -rf /home/USER-NAME/MY-DOMAIN/releases/20110123014150; true" servers: ["bullseye.dreamhost.com"] [bullseye.dreamhost.com] executing command command finished failed: "sh -c 'bundle install --gemfile /home/USER-NAME/MY-DOMAIN/releases/20110123014150/Gemfile --path /home/USER-NAME/MY-DOMAIN/shared/bundle --deployment --quiet --without development test'" on bullseye.dreamhost.com Here is my deploy.rb file. require 'bundler/capistrano' set :user, "MY-USERNAME" set :password, "MY-PASSWORD" set :domain, 'bullseye.dreamhost.com' # Dreamhost servername where your account is located set :project, 'blog' # Your application as its called in the repository set :application, 'MY-DOMAIN' # Your app's location (domain or sub-domain name as setup in panel) set :applicationdir, "/home/#{user}/#{application}" # The standard Dreamhost setup # version control config set :scm_username, 'MY-SVN-USERNAME' set :scm_password, 'MY-SVN-PWD' set :repository, "http://MY-SVN-URL/01/blog/" # roles (servers) role :web, domain role :app, domain role :db, domain, :primary => true # deploy config set :deploy_to, applicationdir set :deploy_via, :export # additional settings default_run_options[:pty] = false # Forgo errors when deploying from windows namespace :deploy do task :start do ; end task :stop do ; end task :restart, :roles => :app, :except => { :no_release => true } do run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}" end end I found a similar question at Bundle install failing when deploying a Rails 3 app to Dreamhost with Capistrano but the solution didn't work. Anybody have any ideas as to what might be happening in my case?
I got this figured out eventually. What I did was ssh into the dreamhost server and execute which bundle command from ssh session execute echo $PATH command edit config/deploy.rb and combine both strings with a : between and place inside default_environment PATH value, see below set :default_environment, { 'PATH' => "'/usr/lib/ruby/gems/1.8/bin//bundle:/home/sayed3/.gems/bin:/usr/lib/ruby/gems/1.8/bin/:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games'" } Once I did this it was able to execute the bundle command successfully, but then I started running into some other issues. I eventually decided to use a VPS that I have hosted elsewhere, but I'm sure if I spent a bit more time I could have figured it out.
Besides adding the path to bundle, as specified above, I also had to add the following line to my config/deploy.rb in order to force capistrano to use bash, instead of the default shell, which, on dreamhost, is dash: set :shell, '/bin/bash'