使用Capistrano升级Bundler版本报gem命令不存在问题排查
Capistrano 批量升级多服务器Bundler版本报
gem: command not found解决方案 故障原因
服务器使用RVM管理Ruby环境,非交互式SSH会话默认不会加载RVM初始化脚本,导致Ruby、Gem等命令的路径未被注入Shell环境变量。原有配置中虽然声明了rvm1:hook的前置钩子,但自定义任务执行时未正确关联RVM上下文,因此直接执行gem install时Bash无法找到对应命令,返回127退出码。
修复步骤
- 重写自定义Bundler安装任务,显式指定命令在RVM管理的目标Ruby版本环境下执行,替换原有
update_bundler.rake的任务代码:
namespace :update_bundler do desc "Install the bundler 2.3.5" task :install do on roles(:all) do rvm_bin = fetch(:rvm1_binary, "$HOME/.rvm/bin/rvm") ruby_ver = fetch(:rvm1_ruby_version, '2.7.2') execute "#{rvm_bin} #{ruby_ver} do gem install bundler -v 2.3.5 --no-document" end end end
- 检查项目根目录下的
Capfile,确认已正确引入rvm1-capistrano3插件,缺失则补加以下行:
require 'rvm1/capistrano3'
- 调整
deploy.rb中的钩子执行顺序,删除原有单独为update_bundler:install绑定的rvm1:hook前置配置,替换为全局Bundler操作前的环境加载逻辑,确保RVM环境先于所有Bundler相关任务加载:
# RVM环境优先加载 before "bundler:install", "rvm1:hook" # 升级Bundler任务在默认bundler:install前执行 before "bundler:install", "update_bundler:install"
- 若仍存在路径识别问题,可在
deploy.rb中补充默认环境变量配置,将RVM及对应Ruby版本的可执行文件路径加入PATH:
set :default_env, { path: [ "$HOME/.rvm/bin", "$HOME/.rvm/rubies/ruby-2.7.2/bin", "$HOME/.rvm/gems/ruby-2.7.2/bin", "$PATH" ].join(":") }
注意事项
- 配置中开启了
.bundle目录的软链接持久化,第一次升级Bundler如果出现版本缓存不匹配的问题,可登录各服务器删除项目shared目录下的旧.bundle缓存文件夹,再重新执行部署即可。 - 正式部署前可先执行干跑命令校验任务顺序是否正确:
cap <部署环境名> deploy --dry-run
确认任务执行链为rvm1:hook -> update_bundler:install -> bundler:install后,再启动正式部署即可批量完成所有服务器的Bundler版本升级。
内容的提问来源于stack exchange,提问作者Umair Khalid
相关产品推荐
相关产品推荐

