Overview
RVM (Ruby Version Manager) manages multiple Ruby installations on Unix-like systems. RVM isolates Ruby versions and their associated gems through separate installation directories and environment modifications. Each Ruby version operates independently with its own gem library, binary executables, and configuration settings.
RVM modifies shell environments dynamically, adjusting PATH, GEM_HOME, GEM_PATH, and other environment variables when switching between Ruby versions. The system maintains a database of installed Rubies in ~/.rvm/rubies/
and manages gemsets within ~/.rvm/gems/
.
The core RVM functionality centers around three primary operations: installation of Ruby interpreters, switching between installed versions, and managing isolated gem environments called gemsets. RVM supports MRI, JRuby, Rubinius, and other Ruby implementations.
# Install and use Ruby 3.2.0
rvm install 3.2.0
rvm use 3.2.0
# Check current Ruby version
ruby -v
# => ruby 3.2.0p0 (2022-12-25 revision a528908681) [x86_64-linux]
RVM operates through shell functions rather than external binaries, requiring proper shell integration for environment management. The system tracks Ruby versions, gemsets, and associated metadata through configuration files and directory structures within the RVM installation directory.
# List installed Ruby versions
rvm list
# Show RVM environment information
rvm info
Basic Usage
Installing Ruby versions through RVM requires specifying the version number or implementation name. RVM downloads source code, compiles the Ruby interpreter, and installs it within the RVM directory structure. The installation process handles dependencies and configuration automatically.
# Install specific Ruby versions
rvm install 3.2.0
rvm install 3.1.4
rvm install jruby-9.4.0.0
# Install with specific configuration
rvm install 3.2.0 --with-openssl-dir=/usr/local/ssl
Switching between Ruby versions changes the active interpreter and associated gem environment. RVM modifies shell environment variables to point to the selected Ruby installation. The switch affects all subsequent Ruby and gem commands in the current shell session.
# Switch to specific Ruby version
rvm use 3.2.0
# Switch with gemset
rvm use 3.2.0@myproject
# Switch and set as default
rvm use 3.2.0 --default
Setting default Ruby versions establishes the Ruby interpreter loaded in new shell sessions. RVM creates symbolic links and updates configuration files to maintain the default selection across terminal sessions.
# Set current Ruby as system default
rvm --default use 3.2.0
# Use system Ruby (bypass RVM)
rvm use system
# Return to RVM Ruby after using system
rvm use default
Gemsets provide isolated gem environments within Ruby versions. Each gemset maintains separate gem installations, preventing conflicts between projects with different dependency requirements. RVM creates gemset directories and manages GEM_PATH modifications automatically.
# Create and use named gemset
rvm gemset create myproject
rvm use 3.2.0@myproject
# Create gemset during Ruby switch
rvm use 3.2.0@newproject --create
# List gemsets for current Ruby
rvm gemset list
# Delete gemset
rvm gemset delete myproject
Installing gems within gemsets isolates dependencies to specific project environments. Gems installed in one gemset remain unavailable to other gemsets, even within the same Ruby version.
# Install gems in current gemset
gem install rails
# Show gemset gem list
gem list
# Empty current gemset
rvm gemset empty
# Copy gemset contents
rvm gemset copy 3.2.0@source 3.2.0@destination
Error Handling & Debugging
RVM installation failures often result from missing system dependencies or compilation errors. The system requires build tools, libraries, and headers for compiling Ruby from source. Missing dependencies cause configure or make errors during Ruby installation.
# Install Ruby with verbose output
rvm install 3.2.0 --verbose
# Check RVM requirements for your system
rvm requirements
# Install system dependencies (Ubuntu/Debian)
rvm requirements run
sudo apt-get install build-essential openssl libreadline6-dev \
zlib1g-dev libssl-dev libyaml-dev libffi-dev
SSL certificate verification errors occur when Ruby installations lack proper OpenSSL configuration. These errors appear during gem installations or HTTPS requests. RVM provides options for specifying OpenSSL paths during Ruby compilation.
# Install Ruby with specific OpenSSL
rvm install 3.2.0 --with-openssl-dir=/usr/local/ssl
# Fix SSL issues for existing installation
rvm osx-ssl-certs status all
rvm osx-ssl-certs update all
# Verify SSL configuration
ruby -ropenssl -e 'puts OpenSSL::SSL::VERIFY_PEER'
Environment loading issues prevent RVM from modifying shell variables correctly. These problems manifest as RVM commands not found or Ruby version switches failing to take effect. Shell integration problems require reloading RVM scripts or checking shell configuration.
# Reload RVM environment
source ~/.rvm/scripts/rvm
# Check RVM function loading
type rvm | head -n 1
# => rvm is a function
# Debug RVM environment
rvm debug
rvm fix-permissions
# Verify shell integration
echo $PATH | grep rvm
Gemset corruption occurs when gem directories become inconsistent or damaged. Symptoms include missing gems, installation failures, or strange gem behavior. RVM provides repair mechanisms for corrupted gemsets.
# Repair gemset
rvm gemset repair myproject
# Rebuild gemset from global
rvm gemset reset
# Clean gemset cache
rvm cleanup all
# Verify gemset integrity
rvm gemset validate
Permission errors appear when RVM directories lack proper ownership or file permissions. These issues prevent Ruby installations, gemset operations, or gem installations from completing successfully.
# Fix RVM permissions
rvm fix-permissions
# Check RVM directory ownership
ls -la ~/.rvm/
# Repair specific Ruby installation permissions
rvm repair 3.2.0
# Reset RVM permissions completely
rvm implode
curl -sSL https://get.rvm.io | bash -s stable
Production Patterns
Production RVM deployments require careful consideration of user permissions, system integration, and deployment automation. Single-user installations provide isolation but require consistent user accounts across servers. Multi-user installations enable system-wide Ruby access but introduce permission complexity.
# Single-user production installation
curl -sSL https://get.rvm.io | bash -s stable --ruby
source ~/.rvm/scripts/rvm
rvm install 3.2.0 --default
# Multi-user system installation
curl -sSL https://get.rvm.io | sudo bash -s stable
sudo usermod -a -G rvm deploy
sudo usermod -a -G rvm www-data
Deployment scripts benefit from RVM wrappers that maintain consistent Ruby environments without shell function dependencies. Wrappers provide direct executable paths for Ruby interpreters and gems, eliminating shell integration requirements.
# Create wrapper scripts
rvm wrapper 3.2.0@production --no-prefix ruby gem rake
# Use wrappers in deployment scripts
#!/usr/bin/env ruby
# This uses the wrapped Ruby binary directly
# Wrapper locations
ls ~/.rvm/wrappers/3.2.0@production/
# => ruby gem rake irb
Container deployments with RVM require careful layer optimization to minimize image size. Installing RVM and Ruby versions in separate Docker layers enables better caching and reduces rebuild times when application code changes.
# Multi-stage Docker build with RVM
FROM ubuntu:20.04 AS ruby-base
RUN apt-get update && apt-get install -y curl gnupg2
RUN curl -sSL https://get.rvm.io | bash -s stable
RUN /bin/bash -l -c "rvm install 3.2.0"
FROM ruby-base AS app
COPY Gemfile* ./
RUN /bin/bash -l -c "rvm use 3.2.0 && bundle install"
COPY . .
CMD ["/bin/bash", "-l", "-c", "rvm use 3.2.0 && bundle exec rails server"]
Monitoring RVM environments requires tracking Ruby versions, gemset status, and gem dependencies across servers. Automated checks verify consistent Ruby installations and detect version drift between environments.
# Environment verification script
#!/bin/bash
source ~/.rvm/scripts/rvm
echo "Current Ruby: $(ruby -v)"
echo "Current gemset: $(rvm gemset name)"
echo "Gem count: $(gem list | wc -l)"
# Check for required gems
bundle check || exit 1
# Verify Ruby version matches expected
expected_ruby="3.2.0"
current_ruby=$(ruby -e "puts RUBY_VERSION")
[[ "$current_ruby" == "$expected_ruby" ]] || exit 1
Configuration management systems require RVM state tracking and idempotent Ruby installations. Chef, Puppet, and Ansible cookbooks manage RVM installations, Ruby versions, and gemset configurations across server fleets.
# Chef cookbook example
rvm_ruby '3.2.0' do
action :install
end
rvm_gemset '3.2.0@production' do
ruby_string '3.2.0'
action :create
end
rvm_gem 'bundler' do
ruby_string '3.2.0@production'
action :install
end
Common Pitfalls
RVM shell integration failures cause the most frequent user issues. RVM functions require proper shell configuration loading, which many users skip during installation. Non-interactive shells, cron jobs, and some IDEs fail to load RVM functions, causing Ruby commands to fail or use system Ruby instead of RVM-managed versions.
# Wrong: Direct RVM usage in scripts without loading
#!/bin/bash
rvm use 3.2.0 # Fails: rvm command not found
# Correct: Load RVM environment first
#!/bin/bash
source ~/.rvm/scripts/rvm
rvm use 3.2.0
Global gemset pollution occurs when users install gems without understanding gemset inheritance. The global gemset for each Ruby version provides gems to all gemsets, but many users inadvertently install application-specific gems globally, causing dependency conflicts across projects.
# Check global gemset contamination
rvm use 3.2.0@global
gem list
# Clean global gemset (dangerous - removes shared gems)
rvm gemset empty global
# Better: Use project-specific gemsets consistently
rvm use 3.2.0@myproject --create
gem install rails
PATH environment variable corruption happens when users modify PATH manually while RVM is active. RVM manages PATH dynamically, and manual modifications often interfere with version switching or create inconsistent Ruby command resolution.
# Wrong: Manual PATH manipulation with RVM active
export PATH="/some/path:$PATH" # Can break RVM switching
# Check PATH for RVM entries
echo $PATH | tr ':' '\n' | grep rvm
# Reset corrupted PATH
rvm reset
source ~/.rvm/scripts/rvm
Default Ruby version confusion arises when users expect RVM defaults to persist across all shell types. Login shells, non-login shells, and interactive vs non-interactive shells load different configuration files, leading to inconsistent default Ruby versions.
# Check default Ruby in different shell contexts
bash -l -c 'ruby -v' # Login shell
bash -c 'ruby -v' # Non-login shell
ssh user@host 'ruby -v' # Remote shell
# Set consistent defaults
rvm alias create default 3.2.0
echo "source ~/.rvm/scripts/rvm" >> ~/.bash_profile
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
Gemfile.lock version conflicts emerge when different developers use different Ruby versions with the same Gemfile.lock. Bundler records the Ruby version in Gemfile.lock, causing warnings or errors when other developers use different Ruby versions.
# Gemfile specifies Ruby version
ruby '3.2.0'
source 'https://rubygems.org'
gem 'rails'
# Wrong: Using different Ruby version
rvm use 3.1.4
bundle install
# => Warning: Ruby version mismatch
# Correct: Match Gemfile Ruby version
rvm use 3.2.0
bundle install
RVM binary conflicts occur when users install Ruby through multiple package managers simultaneously. Having RVM, rbenv, system package managers, or manual Ruby installations creates binary resolution conflicts and unpredictable behavior.
# Check for conflicting Ruby installations
which -a ruby
which -a gem
which -a bundle
# Locate all Ruby binaries
find /usr -name ruby -type f 2>/dev/null
find /usr/local -name ruby -type f 2>/dev/null
# Remove conflicting installations before using RVM
sudo apt-get remove ruby-full # Ubuntu/Debian
brew uninstall ruby # macOS Homebrew
Gemset directory permissions problems prevent gem installations or cause inconsistent behavior across users. These issues appear in multi-user systems where RVM directories have incorrect ownership or restrictive permissions.
# Check gemset permissions
ls -la ~/.rvm/gems/
# Fix ownership recursively
rvm fix-permissions
# Verify write access to gemset
touch ~/.rvm/gems/ruby-3.2.0@myproject/test_write
rm ~/.rvm/gems/ruby-3.2.0@myproject/test_write
Reference
Core Commands
Command | Parameters | Description |
---|---|---|
rvm install <version> |
version string, compile options | Install Ruby version from source |
rvm use <version>[@gemset] |
version, optional gemset, --default flag |
Switch active Ruby version and gemset |
rvm list [known] |
optional known parameter |
Show installed or available Ruby versions |
rvm uninstall <version> |
version string | Remove installed Ruby version |
rvm current |
none | Display current Ruby version and gemset |
rvm default |
none | Switch to default Ruby version |
rvm system |
none | Use system Ruby installation |
rvm reset |
none | Reset to default Ruby version |
Gemset Management
Command | Parameters | Description |
---|---|---|
rvm gemset create <name> |
gemset name | Create new gemset for current Ruby |
rvm gemset use <name> |
gemset name | Switch to gemset within current Ruby |
rvm gemset list |
none | List gemsets for current Ruby version |
rvm gemset delete <name> |
gemset name | Remove gemset and all gems |
rvm gemset empty [name] |
optional gemset name | Remove all gems from gemset |
rvm gemset copy <src> <dst> |
source gemset, destination gemset | Copy gemset contents |
rvm gemset name |
none | Show current gemset name |
rvm gemset dir |
none | Show current gemset directory path |
Installation Options
Option | Description | Example |
---|---|---|
--with-openssl-dir=<path> |
Specify OpenSSL installation path | --with-openssl-dir=/usr/local/ssl |
--with-readline-dir=<path> |
Specify readline library path | --with-readline-dir=/opt/local |
--disable-binary |
Force compilation from source | rvm install 3.2.0 --disable-binary |
--verify-downloads |
Verify checksums of downloads | rvm install 3.2.0 --verify-downloads |
--autolibs=<mode> |
Control automatic library installation | --autolibs=enable |
--movable |
Create relocatable Ruby installation | rvm install 3.2.0 --movable |
Environment Variables
Variable | Purpose | Example Value |
---|---|---|
RVM_PATH |
RVM installation directory | /home/user/.rvm |
GEM_HOME |
Current gemset directory | /home/user/.rvm/gems/ruby-3.2.0@myproject |
GEM_PATH |
Gem search paths | GEM_HOME:global_gem_path |
MY_RUBY_HOME |
Current Ruby installation | /home/user/.rvm/rubies/ruby-3.2.0 |
IRBRC |
IRB configuration file | /home/user/.rvm/rubies/ruby-3.2.0/.irbrc |
Configuration Files
File | Purpose | Location |
---|---|---|
.rvmrc |
Project Ruby version specification | Project root directory |
.ruby-version |
Ruby version specification | Project root directory |
.ruby-gemset |
Gemset specification | Project root directory |
gemsets |
Global gemset list | ~/.rvm/gemsets/ |
wrappers |
Generated wrapper scripts | ~/.rvm/wrappers/ |
Troubleshooting Commands
Command | Purpose | Usage |
---|---|---|
rvm requirements |
Show system dependency requirements | Check before Ruby installation |
rvm debug |
Generate environment debug information | Troubleshoot installation issues |
rvm fix-permissions |
Repair RVM directory permissions | Fix permission-related errors |
rvm cleanup all |
Remove old Ruby installations and downloads | Free disk space |
rvm repair <version> |
Repair specific Ruby installation | Fix corrupted Ruby version |
rvm implode |
Complete RVM removal | Nuclear option for major issues |
Ruby Version Specifications
Format | Description | Example |
---|---|---|
X.Y.Z |
Specific version number | 3.2.0 |
X.Y |
Latest patch version | 3.2 matches latest 3.2.x |
ruby-X.Y.Z |
Explicit MRI specification | ruby-3.2.0 |
jruby-X.Y.Z |
JRuby implementation | jruby-9.4.0.0 |
rbx-X.Y.Z |
Rubinius implementation | rbx-5.0 |
system |
System-installed Ruby | Bypass RVM management |
default |
RVM default Ruby | User-specified default version |