Rails 3和Heroku:在推送时自动“rake db:migrate”?

时间:2011-05-11 14:53:29

标签: ruby-on-rails git heroku

我对我的heroku推送/部署过程感到轻微的烦恼,否则发现和使用它是一种乐趣。

如果我向我的应用添加新的迁移,我可以将它上传到heroku服务器的唯一方法是推送到heroku远程。这会上传并重新启动应用。但它不会运行迁移,所以我必须heroku rake db:migrate --app myapp,然后heroku restart --app myapp。与此同时,应用程序被破坏,因为它没有运行迁移,代码在迁移中引用了字段/表等。

必须有一种方法可以更改部署过程,以便在部署过程中自动运行rake db:migrate,但我无法解决问题。

这是我在heroku cpanel中设置的内容吗?它是从命令行传递给heroku的选项吗?它是一个git钩子吗?谁能让我直截了当?谢谢,最大

10 个答案:

答案 0 :(得分:33)

Heroku现在有能力处理这个问题,作为他们发布阶段的一部分"特征

您可以向release添加名为Procfile的流程,该流程将在每次部署期间运行。

Rails> = 5示例

release: bundle exec rails db:migrate

Rails< 5示例

release: bundle exec rake db:migrate

答案 1 :(得分:32)

这个简单的命令链解决方案怎么样:

git push heroku master && heroku run rake db:migrate

第一个成功完成后,它将自动运行迁移。它的延迟时间为1-2秒或更短。

答案 2 :(得分:29)

这是一个rake任务,它将所有内容包装成一个单行(并且还支持回滚):

https://gist.github.com/362873

你仍然可能最终部署在老板的演示之上,但至少你不会浪费时间在git pushrake db:migrate之间进行输入。

答案 3 :(得分:14)

我创建了a custom buildpack,让Heroku在部署时自动为您运行rake db:migrate。它只是Heroku默认的Ruby buildpack的一个分支,但是添加了rake db:migrate任务。

要在您的应用中使用它,您可以这样做:

heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack

另请注意,要使其正常工作,您需要启用 user-env-compile Heroku Labs功能。这是你如何做到的:

heroku labs:enable user-env-compile

这是我的证据,证明这是有效的:

rake db:migrate on Heroku deployment

答案 4 :(得分:9)

也许您可以尝试从代码提交(模型,验证等)中分离您的架构提交(迁移等)提交。

(请注意,以下假设您的迁移更改不具有破坏性,因为您已指出涵盖了大多数用例。)

您的部署过程可能是:

  1. 将架构更改推送到Heroku
  2. 迁移
  3. 将应用程序代码推送到Heroku
  4. 这当然是最佳形式,但是在您所描述的情况下避免停机的有效方法是:当应用程序收到动态字段的代码时,数据库已经已经迁移。

    (当然,最简单的解决方案就是在老板出去吃饭时简单地推送和迁移;-D)

    否则,即使自动执行架构修改,您仍然会在迁移运行之前冒着请求通过的风险。

答案 5 :(得分:5)

对于像我这样的谷歌搜索人员,我想在这里提供一个简单的解决方案。

我正在使用Rails 4,需要在部署到heroku时添加一个简单的Rake任务。当我使用“部署到heroku' github中的按钮没有机会运行" heroku运行..."部署后立即。

我做了什么:我扩展了在部署到heroku期间自动运行的标准Rake Task资产:clean' 。任务仍然正常运行,但我已将自己的东西附加到它的结束。这是通过'增强' 方法完成的。在下面的示例中,我添加了一个db:migrate,因为这可能是大多数人想要的:

# in lib/tasks/assets_clean_enhance.rake
Rake::Task['assets:clean'].enhance do
  Rake::Task['db:migrate'].invoke
end

我承认这不是完美的解决方案。但是heroku Ruby Buildpack仍然不支持任何其他方式。而编写我自己的构建对于这么简单的事情来说似乎有些过分。

答案 6 :(得分:2)

我使用rake任务将应用程序置于维护模式,推送,迁移并将其从维护模式中移除。

答案 7 :(得分:2)

我编写了SmartMigrate buildpack这是一个简单的Heroku buildpack,用于在检测到新的迁移时,在ruby构建之后警告挂起的迁移。这个buildpack旨在成为具有前面的Ruby buildpack的Multipack的一部分。

在这里适当考虑其他解决方案,这个buildpack比以下有三个优势:

  1. 无需维护模式
  2. 不需要过时插入迁移的过时ruby buildpack分支
  3. 无需一直运行迁移,只有在自上次部署后检测到新的迁移时才会显示警告

答案 8 :(得分:1)

我认为David Sulc的方法是唯一可以确保您在应用处于崩溃状态时避免请求通过的方法。

这有点痛苦,但在某些情况下可能是必要的。

正如他所说,它确实需要db迁移是非破坏性的。

但是,在其余代码之前推送迁移和架构更改可能很困难,因为明显的方法('git push heroku {revnum}')依赖于您在其余部分之前检查了迁移。代码。

如果你还没有这样做,仍然可以使用临时分支来做到这一点:

  • 根据您最近推送到heroku的git修订版创建一个分支:

    git branch <branchname> <revnum-or-tag>
    
  • 查看该分支:

    git checkout <branchname>
    
  • 如果您的数据库迁移仅提交包含的迁移,并且没有代码更改,那么请选择包含数据库更改的提交:

    git cherry-pick <revnum1> <revnum2>...
    
  • 如果您在包含代码更改的修订版中提交了db更改,则可以使用不会自动提交的“git cherry-pick -n”;使用'git reset HEAD'从将要提交的事物集中删除不是db更改的文件。一旦你完成了db更改,就可以在临时分支中提交它们。

    git cherry-pick -n <revnum1> <revnum2>...
    git reset HEAD <everything that's modified except db/>
    git status
    ... check that everything looks ok ...
    git commit
    
  • 将此临时分支推送到heroku(理想情况下是一个临时应用程序,以检查您是否正确,因为避免停机是跳过这些环节的重点)

    git push heroku <branchname>:master
    
  • 运行迁移

    heroku run rake db:migrate
    
  • 此时,您可能认为可以将“master”推送到heroku以获取代码更改。但是,你不能,因为它不是快速合并。继续进行的方法是将“master”的其余部分合并到临时分支中,然后将其合并回master,这将重新组合两个分支的提交历史记录:

    git checkout <branchname>
    git merge master
    git diff <branchname> master
    ... shouldn't show any differences, but just check to be careful ...
    git checkout master
    git merge <branchname>
    
  • 现在您可以正常将master推送到heroku,这将使您的其余代码更改。

在倒数第二步中,我不能100%确定是否需要将master与{branchname}合并。这样做应该确保完成“快进”合并,这样当你推送到heroku时git就会高兴,但是如果没有那个步骤,只需将{branchname}合并到master就可以得到相同的结果。 / p>

当然,如果您不使用'master',请在上面的相关位置替换相应的分支名称。

答案 9 :(得分:0)

我一直在使用heroku_san gem作为我的部署工具。这是一个很好的小型,专注于推送+迁移的工具。它添加了一些其他rake命令,使访问其他功能(如控制台)变得容易。除了不必记住数据库迁移之外,我最喜欢的功能是它的Heroku配置文件 - 所以我可以将我所有的服务器(生产,升级,playground4,shirley)命名为我想要的东西 - 并将它们直接放在我的脑海中。