RVM - System Wide Installs & Capistrano Integration
Following on from the last few posts about rvm, today I’m going to talk about two related but different aspects I’ve been working on – one that makes life easier and one that standardises a process that has been possible for a while but never officially documented (as far as I know). Both are related to making deployment with RVM easier.
System Wide Installs
One of the simplest (yet, hopefully, most useful) things I’ve worked on is the formalization of a way to have a single rvm install for multiple users. It’s been possible for a while but required a little bit of configuration. Now, we’ve made it so that it is as simple to install rvm system wide as it is for a single user. Instead of running:
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )And doing all the configuration work yourself, you will soon be able to run:
bash < <( curl -L http://bit.ly/rvm-install-system-wide )Which will handle almost all it for you. Note that the url before didn’t work – the new one should work correctly (and we plan on hopefully to moving it somewhere more verifiable than bit.ly). If you’re uncomfortable running the above command directly, I suggest doing the alternative (that allows you to inspect the file first):
curl -L http://bit.ly/rvm-install-system-wide > rvm-install-system-wide
# Inspect the file here
bash < ./rvm-install-system-wideLastly, there is a nice handy helper added in /usr/local/lib/rvm so users can simply
add the following to the end of their profile:
[[ -s '/usr/local/lib/rvm' ]] && source '/usr/local/lib/rvm'And it will automatically load rvm from ~/.rvm/ if available, otherwise from the system
wide install at /usr/local/rvm
The Slightly More Technical Explanation
This approach is very similar to that of rvm-install-head except that it also does the following:
- Installs it into /usr/local
- Sets up a group (either set and export
rvm_group_namebefore hand, or use the default of rvm) and adds root as a member - Sets up directory permissions correctly for rvm.
- Sets up /etc/rvmrc correctly for a system-wide install
Please note that this is currently primarily tested on Ubuntu and will not work on OSX. Patches are, as always, welcome. Also, a lot of credit goes to an excellent blog post by Lee Jarvis that has served as the reference up until now and still serves as a reference in terms of the actual implementation.
Simpler Capistrano Support
The second of the production related changes is better capistrano support out of the box with
rvm. First, before I discuss what’s actually involved, please note that this currently
requires the head version of rvm but it will be included in future versions – so either
append ~/.rvm/lib to your load path in the example or require by the absolute path.
Once the next gem version is released, the below code should work as is.
So, without further ado, in new versions of rvm integrating with capistrano has gone from
manually specifying GEM_HOME, GEM_PATH, BUNDLE_PATH, PATH and so on (with a fixed
ruby version) in :default_environment to something as simple as adding the following
to your Capfile:
require 'rvm/capistrano'
set :rvm_ruby_string, 'some-ruby' # Defaults to 'default'And you’re done. Once that’s setup, any command you run in capistrano will be run with the correct environment variables set. Optionally, you also have the following variables you can set that will affect the capistrano script’s behaviour:
-
:rvm_type–:systemor:user– user looks for rvm in$HOME/.rvmwhere as system uses the/usr/localas set for system wide installs. -
:rvm_bin_path– the full path to your rvm install’s bin folder if the above dont work for your setup.
The Slightly More Technical Explanation
This works by taking advantage of the ability to set a default shell for the commands
capistrano calls – in recent commits to rvm, $rvm_bin_path (aka ~/.rvm/bin for most
people) now contains rvm-shell – a thin wrapper around bash that does the following:
- If the first argument doesn’t match
^-, setsrvm_shell_ruby_stringto hold the value of it. - If
rvm_shell_ruby_stringis present, uses the given ruby via rvm (e.g.ree@rails3and the like are supported) - exec bash with the rest of the arguments.
In essence, it means you can startup a bash instance with the environment variables set (but without rvm itself) by doing something similar to:
-
~/.rvm/bin/rvm-shell rbx -c 'which ruby'– should point to rubinius -
rvm_shell_ruby_string=ree ~/.rvm/bin/rvm-shell -c 'which ruby'– should point to ree -
~/.rvm/bin/rvm-shell -c 'which ruby'– should act like a normal bash, system ruby.
The rvm/capistrano basically just tells rvm to override the default capistrano shell
to be rvm-shell.
Conclusion
All of the docs here will be added to the rvm site in the very near future – it’s more as a way to show the work that’s been going in to rvm. It’s worth noting also that this is just the start of the sorts of integration we’ll be working on to making using rvm ith other existing tools even easier.