如何在Fly.io的Rails应用中为Whenever gem传递ENV['DATABASE_URL']?
Rails + Whenever + Fly.io 数据库连接问题解决
问题分析
从错误日志看,系统尝试连接名为thomaskitson的数据库(这是本地系统用户名,Postgres默认会用当前用户名作为数据库名),说明生产环境的rake任务没有正确读取Fly.io的DATABASE_URL环境变量,反而 fallback到了本地默认规则。另外日志中的本地路径也提示:不要在本地直接运行RAILS_ENV=production的任务,这会导致环境不匹配。
解决步骤
1. 修正schedule.rb配置,确保环境变量传递
修改schedule.rb,显式指定任务执行时的环境变量传递逻辑:
# 自定义rake任务的执行模板,确保环境变量正确注入 job_type :rake, "cd :path && DATABASE_URL=#{ENV['DATABASE_URL']} RAILS_ENV=:environment bundle exec rake :task :output" set :environment, :production # 确保部署时能获取到Fly的DATABASE_URL env :DATABASE_URL, ENV['DATABASE_URL'] # 你的定时任务配置示例 every 1.day, at: '3:00 am' do rake 'newspaper:new_images' end
2. 更新database.yml的生产环境配置
即使DATABASE_URL优先级更高,显式配置生产环境避免 fallback:
default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> production: url: <%= ENV['DATABASE_URL'] %>
3. 验证Fly.io上的环境变量与Cron任务
- 检查Fly.io的secrets是否包含正确的
DATABASE_URL:fly secrets list | grep DATABASE_URL - 查看Cron任务详情,确认环境变量已加载:
fly cron list fly cron show <你的定时任务名称> - 在Fly.io机器上手动测试rake任务,排除定时任务的干扰:
fly ssh console -C "cd /app && bundle exec rake newspaper:new_images"
4. 避免本地运行生产环境任务
错误日志中的本地路径说明你可能在本地执行了RAILS_ENV=production的rake任务,本地没有Fly.io的DATABASE_URL,Postgres会默认尝试连接与当前用户名同名的数据库(即thomaskitson),导致错误。生产环境的测试必须在Fly.io机器上通过SSH执行。
内容的提问来源于stack exchange,提问作者Tom Kitson
相关产品推荐
相关产品推荐

