You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Heroku部署Rails应用报Unable to start worker错误排查

Rails部署Heroku后Puma反复报Worker启动失败(Bootsnap指向错误)修复方案

报错核心原因

错误栈指向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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:21:12