Heroku部署Rails应用报Unable to start worker错误排查
报错核心原因
错误栈指向bootsnap的kernel_require.rb只是表象:Bootsnap是Rails默认集成的加载加速组件,所有依赖加载失败的调用栈最终都会落到它的require方法上,并非Bootsnap本身故障。
你本地RSpec遇到的Selenium版本问题和生产环境报错属于同一类根因:Puma worker进程启动阶段加载依赖/应用代码失败,进程直接退出,触发Puma反复拉起worker的循环。
常见触发场景:
- 测试/开发环境专属gem(如selenium-webdriver、capybara、rspec系列)被写到Gemfile全局分组,生产环境安装后因缺少Chrome/Chromedriver等系统二进制依赖,加载时直接抛错
- Bootsnap编译缓存和当前部署的代码、依赖版本不兼容,旧缓存导致加载路径错乱
- Puma配置的worker数、并发数超过Heroku dyno内存上限,worker启动时被OOM杀死
- 应用初始化流程引用了未在Heroku配置的环境变量,加载阶段直接中断
分步修复方案
1. 隔离Gemfile环境分组
打开Gemfile,将所有仅用于开发、测试环境的gem归入对应分组,禁止放在全局作用域:
# 错误写法:全局引入测试依赖,生产环境也会安装加载 gem 'selenium-webdriver' # 正确写法:仅在测试环境引入 group :test do gem 'selenium-webdriver' gem 'capybara' gem 'rspec-rails' # 其他测试专属gem end
如果业务确实需要在生产环境调用selenium,需要额外给Heroku添加Chrome、Chromedriver对应buildpack,否则直接将依赖移入测试分组即可。
修改完成后执行以下命令更新依赖锁文件,提交后重新部署:
bundle install --without production git add Gemfile Gemfile.lock git commit -m "fix: isolate test/dev gems in correct groups" git push heroku main
2. 清除Heroku端Bootsnap旧缓存
Bootsnap缓存残留是该报错最高发的诱因,执行以下命令清除生产环境缓存后重启服务:
heroku run bash # 进入dyno终端后执行 rm -rf tmp/cache/bootsnap* exit # 重启应用 heroku restart
如果要永久避免缓存版本不兼容问题,可以在config/boot.rb中添加配置,部署时自动识别版本失效旧缓存:
# config/boot.rb ENV['BOOTSNAP_CACHE_DIR'] ||= 'tmp/cache/bootsnap' Bootsnap.cache_version = [RUBY_VERSION, Rails.version, Bundler.default_lockfile.stat.mtime.to_i].join('-')
3. 调整Puma配置适配Heroku dyno规格
Heroku 1x dyno仅提供512M内存,2x dyno为1G,禁止硬编码过高的worker数,标准适配配置如下,可直接替换原有config/puma.rb内容:
# config/puma.rb max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } threads min_threads_count, max_threads_count worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } # 1x dyno建议设为1-2个worker,2x dyno可设为2-4个 workers ENV.fetch("WEB_CONCURRENCY") { 2 } preload_app! plugin :tmp_restart
同时确认Procfile启动命令无多余硬编码参数,标准写法如下:
web: bundle exec puma -C config/puma.rb
4. 定位隐藏的初始化报错
如果以上操作完成后仍报错,执行以下命令在Heroku dyno中直接启动Rails控制台,强制加载所有应用代码获取精准报错信息,不要仅依赖Puma抛出的笼统错误提示:
heroku run rails c # 控制台进入后执行强制加载 Rails.application.eager_load!
执行后会直接抛出具体加载失败的文件、依赖或缺失配置项,针对性修复即可。
内容的提问来源于stack exchange,提问作者gurman

