如何将Heroku上的Rails应用迁移至AWS Elastic Beanstalk(原生方案)
从Heroku迁移Rails应用到AWS Elastic Beanstalk(原生方案,含Postgres与定时任务)
刚好我之前帮团队完成过从Heroku到Elastic Beanstalk的Rails应用迁移,完全没用Docker,正好适配你的需求,下面是一步步的实操方案:
一、前期核心配置
你提到的前期准备非常重要,先把这两步落实:
- 设置环境变量:在Elastic Beanstalk控制台进入你的应用环境,找到「配置 > 软件」,把Heroku上所有
config vars(比如RAILS_ENV、SECRET_KEY_BASE、第三方服务密钥等)原封不动填进去,确保应用依赖的变量都能读取到。 - 配置
database.yml:适配AWS RDS Postgres,修改config/database.yml的production节点:
这些production: adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: <%= ENV['RDS_HOSTNAME'] %> port: <%= ENV['RDS_PORT'] %> database: <%= ENV['RDS_DB_NAME'] %> username: <%= ENV['RDS_USERNAME'] %> password: <%= ENV['RDS_PASSWORD'] %>RDS_*变量会在你把RDS实例关联到Beanstalk环境后自动生成,直接引用即可。
二、导出Heroku Postgres数据
用Heroku CLI把现有数据库备份下来:
# 先创建备份 heroku pg:backups:capture # 下载备份到本地 heroku pg:backups:download
执行完会在本地生成一个latest.dump的备份文件,这就是你的数据快照。
三、导入数据到AWS RDS
把备份导入到RDS实例前,先确保RDS的安全组允许你的本地IP访问(不然连不上),然后用psql命令导入:
psql -h <你的RDS主机地址> -U <RDS用户名> -d <RDS数据库名> -f latest.dump
输入RDS密码后等待导入完成,导入过程可能需要几分钟,取决于数据量大小。
四、部署Rails应用到Elastic Beanstalk
先安装AWS EB CLI(如果没装的话),然后完成部署流程:
- 初始化EB项目:
eb init -p ruby-3.2 your-app-name # 替换成你的Ruby版本和应用名称 - 创建生产环境(如果之前没在控制台创建的话):
eb create production-environment - 部署代码:
EB会自动处理资产编译、依赖安装,但第一次部署建议手动跑一次数据库迁移确认:eb deploy# 登录到EC2实例 eb ssh # 进入应用目录执行迁移 cd /var/app/current rails db:migrate RAILS_ENV=production
五、迁移定时任务(Cron Jobs)
Heroku的Scheduler在Beanstalk里可以用CloudWatch Events + EC2 Run Command替代,步骤如下:
- 先把你的定时任务整理到Rails的rake任务里,比如创建
lib/tasks/scheduler.rake:namespace :scheduler do desc "每日清理过期数据" task daily_cleanup: :environment do # 这里写你的任务逻辑 ExpiredData.cleanup! end end - 登录AWS控制台,打开CloudWatch > 事件 > 规则,创建新规则:
- 触发方式选择「计划表达式」,比如
cron(0 12 * * ? *)表示每天UTC时间12点执行(根据你的需求调整) - 目标选择「EC2 Run Command」,指定你的Beanstalk环境对应的EC2实例
- 在命令内容里输入:
cd /var/app/current && bundle exec rake scheduler:daily_cleanup RAILS_ENV=production
- 触发方式选择「计划表达式」,比如
- 给执行命令的IAM角色配置足够的权限,确保能访问EC2实例并执行命令。
六、验证迁移结果
最后做几个关键验证:
- 访问Beanstalk环境的域名,确认应用页面、接口都正常工作
- 随机抽查数据库里的业务数据,和Heroku上的原数据对比,确保没有丢失
- 到定时任务的执行时间后,查看CloudWatch日志,确认任务正常运行
内容的提问来源于stack exchange,提问作者emredurukn
相关产品推荐
相关产品推荐

