Update: @dysinger has subsequently pointed out that he only uses Ruby for infrastructure. His advice (don’t use RVM or similar on servers) is great advice for infrastructure Ruby. Chalk this one up to context-specific advice put forward too generally.
In a conversation where I tried to shoot down some bad advice against the use of rvm (or similar) on servers, @LordCope asked me why I’d want rvm (or similar) on servers, instead of a 12 line shell script or operating system packages.
Why would I want to upgrade Ruby and gemsets on servers?
It’s hard to answer that question without assuming it’s being asked by someone who doesn’t write Ruby applications. If you don’t write Ruby applications, just use your operating system’s Ruby packages. Otherwise…
You develop and test one application against a specific version of Ruby and specific versions of a set of gems.
The next application you develop is tested against a different version of Ruby and different versions of a different set of gems.
Rinse, repeat. Soon, you have many applications on many servers, with different, tested Ruby and gem dependencies.
And now a Ruby security vulnerability is published. It affects some versions of Ruby but not others. The Ruby upgrade demands a rebuild of one of your gems.
Fortunately, that’s an rvm one-liner on each of my workstations, CI, staging and production, for each affected application. One commit to the .ruby-version file in the repo, and the rest is taken care of, globally.
No having to build and distribute a Debian package. No having to tell your CM system to use that Debian package on those servers. You’re done.
And this doesn’t perturb any of your other applications, whether you’ve chosen to co-host them or not, and regardless of when in their lifecycle CM is applied.
Isolation of dependencies is worth much. Just ask any Docker user. But once you have her answer, take a step back and consider that it’s valuable at many levels, and it’s an early exercise of options to lock yourself into a deployment strategy as the only way to get it.
Trying to do this with operating system packages of Ruby demands one or more of
- loads of time,
- an inviolable “one application per instance” rule, or
- shit packaging.
People will argue with the last point. Ask them if they’re packaging all their gems too. If they aren’t, then give them enough time to experience the thrill of a native library update that demands a gemset rebuild and see how strongly opinionated they are then.
Hating on the way rvm and similar tools are implemented is fine. They’re almost always gross band-aids. But to suggest that you should just throw the value they offer away, in the name of myopic simplicity, is foolhardy. And it turns out the simplicity you get isn’t so simple or even easy (multiversion Debian packages for gems, anyone?)