Rails 3和Heroku:自动“rake db:migrate”推?
我对我的heroku推送/部署过程有一点点的烦恼,否则这个过程是一种愉快的发现和使用。
如果我添加一个新的迁移到我的应用程序,唯一的办法,我可以把它放到heroku服务器上是推动到heroku远程。 这会上传并重新启动应用程序。 但它不运行迁移,所以我必须做的heroku rake db:migrate --app myapp
,然后heroku restart --app myapp
。 与此同时,该应用程序已被破坏,因为它没有运行迁移,代码指的是迁移中的字段/表等。
必须有一种方法来更改部署过程来运行rake db:migrate
作为部署过程的一部分自动rake db:migrate
,但我不能解决。
这是我在一个heroku cpanel设置的东西吗? 这是我从命令行传递给heroku的选项吗? 这是一个混帐钩子? 任何人都可以设置我吗? 谢谢,最大
这是一个将所有内容都包装成一行(也支持回滚)的rake任务:
https://gist.github.com/362873
您仍然可能会在您的老板的演示之上进行部署,但至less您不会浪费时间在git push
和rake db:migrate
之间inputrake db:migrate
。
那么这个简单的命令链接解决scheme呢?
git push heroku master && heroku run rake db:migrate
一旦第一个成功完成,它将自动运行迁移。 这大概是1-2秒或更less。
Heroku现在有能力处理这个作为他们的“释放阶段”function的一部分。
您可以将一个名为release
的进程添加到您的Procfile
并在每个部署期间运行。
Rails> = 5例子
release: bundle exec rails db:migrate
Rails <5例子
release: bundle exec rake db:migrate
我创build了一个定制的buildpack ,让Heroku运行rake db:migrate
在部署时自动为你rake db:migrate
。 这只是Heroku默认的Ruby buildpack的一个分支,但添加了rake db:migrate
任务。
要使用它与您的应用程序,你会这样做:
heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack
另外请注意,为了使其工作,您需要启用用户env编译 Heroku实验室function。 以下是你如何做到这一点:
heroku labs:enable user-env-compile
这是我的证据,这是有效的:
也许你可以尝试从代码提交(模型,validation等)中提交模式提交(迁移等)。
(请注意以下假设您的迁移更改不具有破坏性,因为您已经指出涵盖大部分用例。)
您的部署过程可以是:
- 将模式更改推送到Heroku
- 迁移
- 将应用程序代码推送到Heroku
这当然是最佳的forms,但是在描述的情况下避免宕机是一种有效的方法:当应用程序接收到dynamic字段的代码时,数据库将已经迁移。
(当然,最简单的解决办法就是在老板外出吃午饭的时候简单地推送和移动; D)
否则,即使架构修改是自动执行的,在迁移运行之前仍然会冒着请求经过的风险。
对于像我这样的Google用户,我想在这里给出一个简单的解决scheme。
我正在使用Rails 4,需要添加一个简单的Rake任务到部署到heroku。 由于我在github中使用'deploy to heroku'button,因此在部署之后不会立即运行“heroku run …”。
我做了什么:我将在部署期间自动运行的标准Rake Task的资产:“clean”扩展到了heroku。 这个任务仍然正常运行,但我已经附加了自己的东西到最后。 这是用“增强”方法完成的。 在下面的例子中,我添加了一个db:migrate,因为这可能是大多数人想要的:
# in lib/tasks/assets_clean_enhance.rake Rake::Task['assets:clean'].enhance do Rake::Task['db:migrate'].invoke end
我承认这不是完美的解决scheme。 但是Heroku的Ruby Buildpack仍然不支持任何其他的方式。 编写我自己的回修对于如此简单的事情似乎有点矫枉过正。
我使用rake任务将应用程序置于维护模式,推送,迁移并将其从维护模式移出。
我写了SmartMigrate buildpack ,这是一个简单的Heroku buildpack,在检测到新的迁移时发出ruby构build之后的未决迁移警告。 这个buildpack的目的是成为一个具有前面的Ruby buildpack的Multipack的一部分。
在这里尊重其他解决scheme,这个buildpack有三个优势:
- 无需维护模式
- 无需过时的rubybuildpack叉,只是在最后插入迁移
- 无需运行迁移所有的时间,仅当自上次部署以来检测到新的迁移时才显示警告
我认为David Sulc的方法是唯一一个确保您在应用程序处于中断状态时避免请求通过的方法。
这有点痛苦,但在某些情况下可能是必要的。
正如他所说,这确实需要数据库迁移是非破坏性的。
然而,在代码的其余部分之前推进你的迁移和模式变化可能是很困难的,因为明显的方法('git push heroku {revnum}')依赖于你在其他代码之前检查了迁移。
如果你还没有这样做,仍然可以使用临时分支来做到这一点:
-
创build一个分支,基于您最近推送到heroku的git修订:
git branch <branchname> <revnum-or-tag>
-
看看那个分支:
git checkout <branchname>
-
如果您的数据库迁移仅提交包含的迁移并且没有代码更改,请select包含数据库更改的提交:
git cherry-pick <revnum1> <revnum2>...
-
如果你提交的数据库更改也包含代码更改,你可以使用'git cherry-pick -n',它不会自动提交; 使用'git reset HEAD'从一组将要提交的东西中删除不是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,这会重新组合两个分支的提交历史logging:
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>
-
现在,您可以像往常一样将主人推到heroku上,这样就可以让您的代码更改。
在倒数第二步,我不是100%确定是否需要将master与{branchname}合并。 这样做应该确保一个“快进”的合并完成,当你推送到heroku时,git会保持高兴,但是也可以通过在没有这个步骤的情况下将{branchname}合并到master来获得相同的结果。
当然,如果你不使用“主”,在上面的相关位置replace适当的分支名称。
我一直在使用heroku_san gem作为我的部署工具。 这是推送+迁移的一个很好的小工具。 它增加了一些其他的rake命令,使访问其他function(如控制台)变得简单。 除了不需要记住数据库迁移之外,我最喜欢的function就是它的Herokuconfiguration文件 – 所以我可以随意命名我的所有服务器(生产,分段,playground4,shirley),并且让它们保持在我的头脑中。