Capistrano rbenv - Ruby version not installed witn dry run - ruby-on-rails

When I run Capistrano task with dry run it tells me that rbenv Ruby version can't be found. I assume with dry run it should use local environment. But when I run the commands locally I can easily find below mentioned directory and Ruby is installed.
> ./bin/bundle exec cap --dry-run development t
DEBUG [8171d925] Running [ ! -d ~/.rbenv/versions/2.4.3 ] as user#dev
DEBUG [8171d925] Command: [ ! -d ~/.rbenv/versions/2.4.3 ]
ERROR rbenv: 2.4.3 is not installed or not found in ~/.rbenv/versions/2.4.3
> ls ~/.rbenv/versions/2.4.3
bin include lib share
> rbenv global
2.4.3
> ruby -v
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-darwin16]
> bundle info capistrano
* capistrano (3.4.0)
My Capfile contains below lines.
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.4.3'
I'm using Mac OS and installed rbenv with homebrew.

Check your PATH and make sure it contains $HOME/.rbenv/shims and $HOME/.rbenv/bin
To view your path do:
$ echo $PATH
Also check that you have the following in your ~/.bash_profile
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
To check bash profile enter in terminal:
touch ~/.bash_profile; open ~/.bash_profile
Make sure it's the last setting in your ~/.bash_profile

There must have been some bug in capistrano/rbenv. I have changed my Gemfile as follows and problem is solved.
# gem 'capistrano-rbenv', '2.0.2'
gem 'capistrano-rbenv', '~> 2.1'

I assume with dry run it should use local environment.
This is not true.
A Capistrano dry-run simply prints out the remote commands that it would run in an actual deploy, but it does execute them at all (local or otherwise).
Since Capistrano is not executing any commands, any plugins that rely on results of those commands may not work. For example, the rbenv plugin is apparently expecting to run this command:
[ ! -d ~/.rbenv/versions/2.4.3 ]
In a dry-run scenario, this is not actually executed. Instead, Capistrano just prints the command and continues as if the command succeeded.
In this particular case, for [ ! -d ~/.rbenv/versions/2.4.3 ] to "succeed" means that the ~/.rbenv/versions/2.4.3 does not exist. The rbenv plugin thus prints an error an halts the deployment.
To summarize: in practice, the --dry-run option is not particularly useful.

Related

AWS EC2 Default Ruby Version on Login

so I have my rails project hosted with AWS EC2 using the amazon linux server. by default, ruby -v returns ruby 2.0 but my project was designed on 2.3.3 (latest at the time). in order for me to change the ruby version using rbenv i have to run the following every time i log in via ssh
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ ~/.rbenv/bin/rbenv init
$ source ~/.bash_profile
$ eval "$(rbenv init -)"
$ type rbenv
since i have the global ruby version in rbenv set as 2.3.3 already.
then i can run
$ ruby -v
#returns 2.3.3
$ rails s
#or any other rails commands
is there any way I can set it so I don't have to edit the .bash_profile every time?
what I get if I run the above code, then exit the ssh, and ssh back in
$ ruby -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
$ rbenv global
2.3.3
$ rbenv local
2.3.3
$ rails s
-bash: rails: command not found
##### run above code and nothing else #####
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]
$ rails s
# starts rails server without issue
It should work without your ritual after every log in. I believe you don't quite understand what's going on there. Let's start it line by line.
# add init of rbenv on every login to the file .bash_profile to make available rbenv CLI
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
# call rbenv native initializer for first time only (it shows you what else you could do for rbenv)
$ ~/.rbenv/bin/rbenv init
# read and execute .bash_profile (string in echo in the first cmd)
$ source ~/.bash_profile
# as far I remember it isn't used anymore
$ eval "$(rbenv init -)"
# this is just a smoke test to check if rbenv works
$ type rbenv
Once you completed it, you don't need to do it on the next logins, because it should be run automatically. If this doesn't work you could try to replace .bash_profile to .bashrc in the commands above.
In order to fix the version of ruby use this reference

Chef deployed Puma server with a Sidekiq worker fails with incorrect ruby version error

This rails app's puma/runit service has been working up until I tried to deploy the Sidekiq 3.5.3 gem with my app via chef
In my recipe I've installed 2.0.0p576 via ruby_build recipe
which ruby #gives me /usr/bin/ruby
/usr/bin/ruby -v #return 2.0.0p576
templates/default/sv-myapp-run.erb
echo "$(ruby -e 'print RUBY_VERSION')" >> check_ruby.txt #returns 2.0.0
exec chpst -u root:root bundle exec puma --config config/puma.rb
Inside the log of the runit service I get this message below
2015-11-04_06:23:50.99541 /var/lib/gems/1.9.1/gems/sidekiq-3.5.3/lib/sidekiq.rb:3:in `<top (required)>': Sidekiq 3.5.3 does not support Ruby 1.9. (RuntimeError)
As this doesn't occur locally - I'm led to believe it has something to do with Chef and how I'm setting up Ruby on the host
I've also tried installing rvm , purging system ruby and have confirmed the default (global and local) as > 2.0 - none of this has made a difference yet.
I noticed in /usr/local/bin/puma the declaration is
#!/usr/bin/env ruby1.9.1
I edited this to just be ruby - then restarted the service but no change. Is there a way I can force Puma to run under ruby +>2.0 ?
ruby_build_ruby '2.0.0-p576'
link "/usr/bin/ruby" do
to "/usr/local/ruby/2.0.0-p576/bin/ruby"
end
gem_package 'bundler' do
options '--no-ri --no-rdoc'
end
include_recipe "runit"
deploy_revision("/opt/deploy") do
revision "develop"
repository "removed"
user "root"
action :deploy
shallow_clone true
keep_releases 3
rollback_on_error true # remove release if callbacks failed
migrate true
migration_command "rake db:migrate"
before_migrate do
execute "bundle install" do
command "bundle install"
cwd "#{release_path}"
user "root"
end
end
#restart_command "rails server -b 0.0.0.0"
# disable default behavior
symlink_before_migrate.clear
create_dirs_before_symlink.clear
purge_before_symlink.clear
symlinks.clear
end
Ubuntu 14.04 , Bundler 1.10.6
Thanks!
I don't think the ruby you've installed is the default for the system (or at least, not when Chef executes bundler). I'm basing that on /var/lib/gems/1.9.1/gems/sidekiq-3.5.3 which seems to indicate you've installed the gem under 1.9.1 as well.
I don't know if you have a preference for rvm or rbenv, but each has a popular community cookbook that can set the default system ruby to the one you want to use, or even just for a particular user (since you're using root, I'd say just set the system ruby as the one you want).
If you were using the rbenv cookbook, it would look like this:
include_recipe 'ruby_build'
include_recipe 'ruby_rbenv'
rbenv_global '2.0.0p576'
You would also be able to omit these resources you were using before:
ruby_build_ruby '2.0.0-p576'
link "/usr/bin/ruby" do
to "/usr/local/ruby/2.0.0-p576/bin/ruby"
end
Also, I'd recommend running as another user than root, so you can only break that user's default ruby instead of the entire system's ruby. Cheers!

Unicorn crashing because of using wrong ruby version after deployment

I am having trouble launching my application in the server because of the following error:
/home/blabla/.rvm/gems/ruby-2.1.0/bin/ruby/2.1.0/bin/unicorn", "-E", "beta", "-c", "/var/www/testenvir/releases/20141117005244/config/unicorn.rb", "-D", {16=>#<Kgio::UNIXServer:fd 16>}] (in /var/www/testenvir/releases/20141121053734)
/home/blabla/.rvm/gems/ruby-2.1.0#global/gems/bundler-1.6.3/lib/bundler/definition.rb:390:in `validate_ruby!': Your Ruby version is 2.1.0, but your Gemfile specified 2.0.0 (Bundler::RubyVersionMismatch)
The error is self descritive, but i don't know how to fix it since i have in my Gemfile script:
ruby '2.0.0'
And in my capistrano deployment script:
set :rvm_ruby_string, 'ruby-2.0.0-p353'
set :bundle_dir, "/home/blabla/.rvm/gems/ruby-2.0.0-p353/bin"
In my server, i set my environment variables as following:
rvm use ruby-2.0.0-p353
And the output of env RAILS_ENV=testenvir bundle exec ruby -v is :
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
I could verify by connecting through a new terminal that rvm listproduces :
=* ruby-2.0.0-p353 [ x86_64 ]
ruby-2.1.0 [ x86_64 ]
Finally my crashing command is defined in the eye script that tries launching the following command:
bundle exec unicorn -E #{RAILS_ENV} -c #{working_dir}/config/unicorn.rb -D
I verified that #{working_directory} and #{RAILS_ENV} are correct, so i thought about hardcoding ( as a first step), the paths of bundleand unicorn, since they are the one taken from the 2.1.0 instead of the 2.0.0-p353 ( The error that i get in unicorn.log... ), but it didn't work ( crashed with another error...)
I also checked $PATH, $GEM_HOME, $GEM_PATH and $RUBY_VERSION, and they were all pointing to the version 2.0.0-p353. In fact, i did a printenv and looked for a potential variable with ruby-2.1.0 assigned to it, but i found none !
I checked all files of my application to wether i am assigning ruby-2.1.0 somewhere anyhow, but i didn't find any reference to that. All of them were set to ruby-2.0.0-p353.
My question is :
Is there another place that i am missing where should i specify my desired ruby version ? How should i set my ruby version in the server rather that what i did ?
Thanks!
UPDATE:
rvm current
ruby-2.0.0-p353
rvm gemset list
gemsets for ruby-2.0.0-p353 (found in /home/deployer/.rvm/gems/ruby-2.0.0-p353)
=> (default)
global
A little late but could help others who are experiencing the same problem. I´m using rolling restart and what helped me was this comment which I have in my config/unicorn.rb file
# If you roll off old code from your app servers (i.e. the way chef, capistrano,
# basically anyone does it) you need to make sure Unicorn is not looking for
# the Gemfile it was originally started with. It's really important that after
# change you stop/start unicorn after first redeploy.
# After that the "before_exec" block will go in memory and
# wait for the next deploy!
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "#{root}/Gemfile"
end
So then I ran
/etc/init.d/unicorn-myapp stop
/etc/init.d/unicorn-myapp start
and unicorn picked up the new ruby version.

Installing Ruby with rvm1-capistrano3

When I run
cap production rvm1:install:ruby
I get this error at the end of the console output:
Command: cd ~/apps/foo/releases/20140121133714 && ( PATH=/opt/ruby/bin:$PATH /usr/bin/env /tmp/foo/rvm-auto.sh rvm install . )
Could not determine which Ruby to use; . should contain .rvmrc or
.versions.conf or .ruby-version or .rbfu-version or .rbenv-version, or an appropriate line in Gemfile.
cap aborted!
EDIT
After adding an .ruby-version at the root of my app, with the contents I get
DEBUG [af3b80bc] Command: cd ~/apps/foo/releases/20140121160854 && /usr/bin/env /tmp/foo/rvm-auto.sh rvm install .
DEBUG [af3b80bc] ruby-2.0.0-p247 is not installed.
DEBUG [af3b80bc] To install do: 'rvm install ruby-2.0.0-p247'
DEBUG [af3b80bc] ruby-2.0.0-p247 is not installed.
DEBUG [af3b80bc] Searching for binary rubies, this might take some time.
DEBUG [af3b80bc] ruby-2.0.0-p247 is not installed.
DEBUG [af3b80bc] Searching for binary rubies, this might take some time.
DEBUG [af3b80bc] No binary rubies available for: ubuntu/12.10/x86_64/system.
DEBUG [af3b80bc] Searching for binary rubies, this might take some time.
DEBUG [af3b80bc] Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies.
DEBUG [af3b80bc] Searching for binary rubies, this might take some time.
DEBUG [af3b80bc] RVM does not have prediction for required space for system, assuming 150MB should be enough, let us know if it was not.
DEBUG [af3b80bc] Searching for binary rubies, this might take some time.
DEBUG [af3b80bc] Either the ruby interpreter is unknown or there was an error!.
I'm running Capistrano 3.1.1 with rvm1-capistrano gem. It's out of the box implementation; nothing special going on.
group :development do
gem 'capistrano', '~> 3.1.0'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'rvm1-capistrano3', require: false
# gem 'capistrano-rvm'
end
# capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/bundler'
require 'rvm1/capistrano3'
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
I'm also getting two other errors in the output:
Running /usr/bin/env [ -L ~/apps/foo/releases/20140121135720/public/assets ] on foo.com
Command: [ -L ~/apps/foo/releases/20140121135720/public/assets ]
Finished in 0.291 seconds with exit status 1 (failed).
Running /usr/bin/env [ -d ~/apps/foo/releases/20140121135720/public/assets ] on foo.com
Command: [ -d ~/apps/foo/releases/20140121135720/public/assets ]
Finished in 0.295 seconds with exit status 1 (failed).
Problem
If you go to the remote server and execute this:
cd ~/apps/foo/releases/20140121160854 && /usr/bin/env /tmp/foo/rvm-auto.sh rvm install .
you will get the same error but if you execute this instead
cd ~/apps/foo/releases/20140121160854 && /usr/bin/env /tmp/foo/rvm-auto.sh rvm install ruby-2.0.0-p247
success.
The problem appears when rvm-auto.sh execute the rvm install . command. Not sure if is a rvm problem but it looks so to my eyes..
Workaround
If you specify the desired version of ruby to install in config/deploy.rb:
set :rvm1_ruby_version, "ruby-2.0.0-p247"
before executing any rvm1 tasks. Everything should be fine
The application does not know which version of ruby to use.
All you need to do is add a file called .ruby-version to the root of your application, and have its contents be
1.9.3
Or whatever version of ruby you are using.
You may also need a .ruby-gemset file. In which case, its contents should be
some_gemset_name
You can call your gemset whatever you want. It is local to your application.

Rails 3 -- Bundler/Capistrano Errors

I have a basic Rails 3 app working locally on my development box, but want to test out deploying early on to make sure everything works. I'm using Capistrano to deploy.
When I run cap deploy (after all the other necessary setup), it breaks on this command with this error:
[...]
* executing 'bundle:install'
* executing "bundle install --gemfile /var/www/trex/releases/20100917172521/Gemfile --path /var/www/trex/shared/bundle --deployment --quiet --without development test"
servers: ["www.[my domain].com"]
[www.[my domain].com] executing command
** [out :: www.[my domain].com] sh: bundle: command not found
command finished
[...]
So it looks like it can't find the bundle command on the server.
However, when I log in to the server...
$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
$ rails -v
Rails 3.0.0
$ bundle -v
Bundler version 1.0.0
...the bundle command works just fine.
What could be going wrong?
-
(Furthermore, for completeness:)
$ which ruby
~/.rvm/rubies/ruby-1.9.2-p0/bin/ruby
$ which rails
~/.rvm/gems/ruby-1.9.2-p0/bin/rails
$ which bundle
~/.rvm/gems/ruby-1.9.2-p0/bin/bundle
UPDATE:
For RVM >= 1.11.3, you should now just use the rvm-capistrano gem. For older RVM >= 1.0.1, the answer below still applies.
ORIGINAL ANSWER:
Okay, though I still haven't gotten a full cap deploy to work, I did fix this problem. The problem was Capistrano trying to use a different path for Bundler (and other gems) than the RVM paths.
Check your Capistrano path by doing cap shell, then echo $PATH. You'll probably see your standard /usr/local/bin and /usr/bin, but that's not where RVM has Bundler, et al., stored.
Edit your Capistrano config/deploy.rb file, and add the following lines, per these instructions:
# Add RVM's lib directory to the load path.
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
# Load RVM's capistrano plugin.
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.2'
set :rvm_type, :user # Don't use system-wide RVM
That finally got Capistrano to see Bundler and start loading gems appropriately.
Bundler isn't found because .bash_profile is not being loaded and thus your PATH is wrong. This is probably because you have the RVM script in .bash_profile.
The simple answer is to move the RVM script from .bash_profile to .bashrc and Capistrano should be able to find it (also verify that .bash_profile sources .bashrc).
Capistrano uses SSH to execute commands on the server via a non-interactive shell. This shell session will source .bashrc but not .bash_profile. I added an ECHO statement to both and ran an LS via SSH. You can see in the results below that only .bashrc is sourced:
$ ssh user#123.amazonaws.com ls
.bashrc loaded
git
file1
file2
I had an identical problem using rbenv. The solution was to take the rbenv specific lines from the bottom of my .bashrc file and put them at the top. The first line of my .bashrc file was returning aborting if the shell wasn't running in interactive mode.
That last line should actually be
set :rvm_type, :user
that is, user must be a symbol and not a variable, otherwise you'll get
undefined local variable or method `user'
No rvm/capistrano worked for me. The best solution I found was adding to deploy.rb file the following line (it's for non system-wide RVM):
set :bundle_cmd, 'source $HOME/.bash_profile && bundle'
It was my understanding that the bundle command is not found because the PATH variable, defined in the user's ~/.bash_profile, isn't loaded by Capistrano.
To get around this I have created a task :bundle_gems.
task :bundle_gems do
run "cd #{deploy_to}/current && export PATH=/usr/local/pgsql/bin:/opt/ruby-enterprise-X.X.X/bin:$PATH && bundle install vendor/gems"
end
Note that I also include the path to PostgreSQL binaries - installation of the pg gem was failing because they could not be found, even when bundle could be found.
This seems like a messy approach, though. Presumably there is a more 'global' place to define paths to binaries that I don't know about.
Update 23/12
To add a directory to $PATH for all users: https://serverfault.com/questions/102932/adding-a-directory-to-path-in-centos
However this still won't be loaded because it is a non-interactive non-login shell.
One suggestion was to add the paths to /etc/bashrc: How do I set $PATH such that `ssh user#host command` works?
However this also didn't work for me. I believe its because SSH doesn't load /etc/bashrc either.
Another suggestion was to edit ~/.ssh/environment: http://www.ruby-forum.com/topic/79248. However this seems almost as messy as specifying the paths in deploy.rb.
This one worked for me:
set :bundle_cmd, 'source $HOME/.bash_profile && bundle'
I tried a number of the suggestions. Had problems with setting the paths in the deploy.rb file for the RVM environment. My final solution was to include the following:
In the config/deploy.rb file add:
require "bundler/capistrano"
Also in config/deploy.rb, or in my case config/production.rb as I was using the multistage option for Capistrano
after "deploy", "rvm:trust_rvmrc"
This step simply ensures that we stop getting the 'do you want to trust the .rvmrc file' and it calls a task in the deploy.rb file such as:
namespace :rvm do
task :trust_rvmrc do
run "rvm rvmrc trust #{release_path}"
end
end
After putting in these slight changes I was able to run cap production deploy which checked out the code; executed the asset pipeline deployment, linked up the release folder to current, executed bundle install and cleaned up.

Resources