I have an ancient Ruby on Rails project that uses a Capistrano installation process. It currently runs Ruby 2.5.1 and Rails 5.2. I have been working on an updated version and while doing so probably have messed up the old installation. Right now I need to repair the Capistrano deployment process to install a fix before migrating to the new situation.
I use rvm to manage the different Ruby versions.
On my local machine, the app runs fine using ruby
2.5.1, gem
3.2.3, bundle
1.17.3. This is also the bundle version stated in Gemfile.lock.
On the server, there is ruby
2.5.1, gem
2.7.6 and bundle
1.16.1. (rvm is also installed.) When deploying, I get the error message rubygems.rb:289:in 'find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
. In fact, running gem list bundle
in the current directory (the version of the software that is still running) tells me that the current version of bundle
is 1.16.1. However, the Gemfile.lock of the currently running version of the software states it was bundled with 1.17.3.
I think I should probably install bundle
1.17.3 on the server as it really does not seem to be installed (in /home/deploy/.rvm/gems/ruby-2.5.1/gems/). However, I think that before I start installing things on a running production server I should be clear about what I am doing, hence my questions.
gem
(RubyGem) version connected to the Ruby version? The versions listed on my machine and on the server seem to suggest that the RubyGems version should match the Ruby version. Is that true?gem
(RubyGems) determined? (My guess: rvm does it, but how?) I am particularly interested in how the version 2.7.6 got onto the server since Ruby 2.7.6 is not installed.gem
(RubyGems), and if so, how does it know which version to install?bundle
1.17.3 installed on the server, and why does this break installation now?And finally, more because I always get confused:
RubyGems is a LIBRARY (a bunch of Ruby code) that comes installed with Ruby. This library allows you to install gems (gem install something
), and it also allows you to load those gems from your programs (require 'some_gem'
). So in summary it is a bunch of code that allows you to make use of gems and everything that comes with the gem ecosystem (installation, management, usage).
Physically you can find the RubyGems code here:
https://github.com/rubygems/rubygems
You can read the description of that repository.
gem
and bundle
commands, and how are they related to RubyGems and Bundler?gem
is just the command which allows you as a human to interface with the RubyGems library code, that I just referenced above.
It is not more nor less complex than that. When you run the gem
command, it will load the RubyGems library code from the Ruby installation (which I just showed you where to find the code on GitHub). Then the gem
command calls the appropriate methods in this library, in order to fulfill your request (remove a gem, install a gem, query information about a gem, and so forth).
Bundler and the bundle
command are no different. Bundler is also a library of code, and bundle
is the command to interface with this code, but instead of installing and managing gems system-wide, like RubyGems allows you to do, Bundler allows you to manage and install gems on just a project basis. So think of Bundler as kind of a project-isolated gem manager. This as opposed to RubyGems, which is a system-wide gem manager.