Migration from rvm to chruby on production
On our rails and worker servers at flinc, we recently migrated the ruby version management from rvm to chruby.
Besides the usual arguments against rvm, like preferring unpatched cd commands, there was another reason:
The fnichol’s chef rvm cookbook has some issues.
Issues I experienced using the rvm cookbook
rvm::user_install
The rvm::user_install recipe fails, because it’s trying to find rvm in a wrong path (the global one). This can be fixed by setting a symlink before installing rvm
link '/bin/rvm' do
to '/home/vagrant/.rvm/bin/rvm'
end
include_recipe 'rvm::user_install'
rvm_ruby '1.9.3' do
user 'vagrant'
end
file '/bin/rvm' do
action :delete
end
rvm_gem
The rvm_gem LWRP doesn’t chown the target directly correctly (needs to belong to the user), when using user_install). It needs to be fixed with a manual chown
rvm_gem 'bundler' do
user 'vagrant'
ruby_string '1.9.3@mygemset'
end
directory '/home/vagrant/.rvm' do
owner vagrant
group vagrant
recursive true
end
bash defunct processes (zombies)
Some LWRP/recipe in fnichols cookbook leave zombies behind, shown when having a look at the ps tree. Those zombies where occurring on every server where the fnichol rvm cookbook was used.
$ ps axfu
root 8887 0.1 1.1 153668 60756 ? Sl Jul07 8:33 chef-client
root 30498 0.5 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 30545 0.7 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 30634 0.7 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 30757 0.6 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 30897 0.8 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31149 0.7 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31236 0.8 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31359 0.7 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31499 1.0 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31622 0.9 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
root 31745 0.8 0.0 0 0 ? Z 16:05 0:00 \_ [bash] <defunct>
As great as a tool as rvm is on your workstation machine, on a (production) server, you usually do not need multiple ruby versions and gemsets, but a clean and stable environment.
Migrating to chruby
The new setup is using fnichol’s ruby-build cookook, as well as the chruby cookbook from Atlanta.
For system processes (like chef-client), I think it’s a good idea to stick to the systems ruby (therefore setting it as a default), while the application uses chruby to select its ruby version. This is how the chruby chef recipe in my wrapper looks like:
# install ruby_build
include_recipe 'ruby_build'
# build and install ruby
ruby_build_ruby node['app-rails']['ruby-string'] do
prefix_path "/opt/rubies/#{node['app-rails']['ruby-string']}"
end
# install chruby
node.default['chruby']['default'] = 'system'
include_recipe 'chruby'
# install bundler
gem_package 'bundler' do
gem_binary "/opt/rubies/#{node['app-rails']['ruby-string']}/bin/gem"
end
migrating rvm wrapper to chruby-exec
For starting up services or tasks like “bundle install”, you can use chruby-exec, which works just as smooth as an rvm wrapper.
chruby-exec 1.9.3-p448 -- bundle install