共享主机环境下Passenger与Ruby如何配置部署Ruby on Rails应用
问题根源
核心矛盾是shell执行环境与Passenger运行环境的Ruby版本、Bundler路径、gem存储路径三者不匹配:
- 你执行
bundle install时使用的是Ruby 2.5.5环境,所有gem都会被安装到2.5.5对应的gem存储目录;但Passenger绑定的是主机预装的Ruby 2.7.4,只会在2.7.4对应的系统gem路径、应用本地gem路径检索依赖,自然无法找到你用2.5.5环境安装的rake等gem包。 - 当你在Gemfile中添加
ruby 2.7.4声明时,你当前shell使用的Ruby版本为2.5.5,低于Gemfile声明的版本要求,因此bundle install会直接校验失败无法执行。
Passenger与cPanel配置的协同逻辑
cPanel的Application Manager生成应用配置后,会自动在站点根目录的.htaccess文件中写入转发规则,将对应域名的所有请求转发给Passenger处理:
- Passenger会主动读取应用根目录下的
config.ru、.bundle/config、Gemfile.lock文件,解析应用的运行环境要求。 - 共享主机环境下的Passenger默认调用cPanel预装的系统Ruby版本(你当前场景对应
ea-ruby27),不会读取你在shell中自定义的Ruby版本环境变量,因此你手动切换的Ruby版本对Passenger完全无效。
修复操作步骤
- 先将shell的Ruby版本切换到与Passenger绑定的版本完全一致:在cPanel的「Setup Ruby」界面选中当前应用对应的Ruby 2.7.4虚拟环境,点击进入虚拟环境,执行
ruby -v确认输出为2.7.4,执行which bundle确认输出路径在ea-ruby27的目录范围内。 - 清理旧的依赖缓存:在应用根目录执行
rm -rf .bundle vendor/bundle Gemfile.lock。 - 修改Gemfile,取消
ruby '2.7.4'行的注释,删除ruby '2.5.5'的相关声明。 - 执行依赖安装命令:
bundle install --deployment --without development test,该参数会将所有gem安装到应用根目录下的vendor/bundle路径中,与系统gem目录完全隔离。 - 验证依赖安装结果:执行
bundle exec gem list rake,确认rake 13.0.6已经在输出列表中。 - 在应用根目录创建
tmp/restart.txt文件,触发Passenger重启应用即可生效。
共享主机部署注意事项
- 不要使用rvm、rbenv这类第三方Ruby版本管理工具,共享主机的Passenger不会读取这类工具的环境变量,必须使用cPanel官方提供的预装Ruby版本和对应虚拟环境。
- 所有和bundler相关的操作,都必须在对应应用的cPanel Ruby虚拟环境下执行,不能使用默认shell的Ruby环境。
- 生产环境安装依赖必须添加
--deployment参数,确保所有依赖都安装到应用自身的目录下,Passenger会自动识别该路径下的gem包。
内容的提问来源于stack exchange,提问作者dirktay
相关产品推荐
相关产品推荐

