Skip to content

rbenv and capistrano Notes

Matijs van Zuijlen edited this page Jan 4, 2024 · 8 revisions

Here are a few notes on how to get whenever to work correctly with rbenv deployed server-wide in /opt/rbenv. This is using Capistrano 3 with capistrano rbenv integration.

Add this line in your Capfile:

require 'capistrano/rbenv'
require 'whenever/capistrano'

Add those lines to your deploy.rb

##
# Rbenv Setup
set :rbenv_custom_path, '/opt/rbenv'
set :rbenv_type, :system
set :rbenv_ruby, '2.3.2'
rbenv_prefix = [
  "RBENV_ROOT=#{fetch(:rbenv_path)}",
  "RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
]
set :rbenv_prefix, rbenv_prefix.join(' ')
set :rbenv_map_bins, %w(rake gem bundle ruby rails)
set :bundle_binstubs, -> { shared_path.join('bin') }


# Configure 'whenever'
vars = lambda do
  "'environment=#{fetch :whenever_environment}" \
  "&rbenv_root=#{fetch :rbenv_custom_path}" \
  "&rbenv_version=#{fetch :rbenv_ruby}'"
end
set :whenever_variables, vars

Finally, add those lines into your schedule.rb:

set :rbenv_root, '/opt/rbenv'
set :rbenv_version, '2.3.3'
env 'RBENV_ROOT', rbenv_root
env 'RBENV_VERSION', rbenv_version

This way, whenever will be executed with the right ruby in capistrano, and your scheduled actions will run with the right ruby version from rbenv, as specified in your capistrano config

mdesantis' solution

This solution takes advantage of rbenv exec:

  • config/deploy.rb
# Whenever config
set :whenever_environment, fetch(:stage)
set :whenever_identifier, "#{fetch(:application)}_#{fetch(:stage)}"
set :whenever_variables, -> do
  "'environment=#{fetch :whenever_environment}" \
  "&rbenv_root=#{fetch :rbenv_path}'"
end
  • config/schedule.rb
# Whenever config
if @rbenv_root
  job_type :rake,    %{cd :path && :environment_variable=:environment :rbenv_root/bin/rbenv exec bundle exec rake :task --silent :output}
  job_type :runner,  %{cd :path && :rbenv_root/bin/rbenv exec bundle exec rails runner -e :environment ':task' :output}
  job_type :script,  %{cd :path && :environment_variable=:environment :rbenv_root/bin/rbenv exec bundle exec script/:task :output}
end

mvz's solution

By default, whenever runs tasks with bash -l -c .... This is configured using :job_template. This runs the job inside a login shell, which means ~/.bash_profile is loaded if present. Because of this, initializing rbenv inside ~/.bash_profile (instead of the usual ~/.bashrc) makes rbenv work inside the cron jobs.