Heroku + Github 部署策略

15
我在开发一个网络应用程序,将源代码托管在Github上并在Heroku上运行该应用程序。一切都很好,但我有一个问题无法解决。在部署我的代码之前,我运行一些脚本来优化代码(缩小、合并文件等)。Heroku应用程序仅使用优化版本的应用程序。
基本上,我有两个文件夹:devproductionDev包含我编写的源代码,production是由我的构建脚本生成的(我使用grunt和requirejs)。目前,这两个文件夹都在我的Git存储库中,并且都被推送到Github和Heroku。我希望只在Github上有dev,而只在Heroku上有production。 我阅读了一些文章,了解如何为Heroku设置不同的分支,如此博客中所述。我可以设置生产分支并仅在其中放置production文件夹,同时保留dev文件夹在我的主分支吗?还是我需要单独的存储库?
有人尝试过类似的事情吗?我认为这不是什么特别的事情。
4个回答

7

您可能希望考虑使用heroku的.slugignore文件(参考https://devcenter.heroku.com/articles/slug-compiler)。

这个文件可以让您从heroku部署到每个服务器实例的包中删除dev文件夹,同时允许您将所有代码保存在同一个存储库中。

问题的根源在于将部署策略视为上传最终位到服务器的策略,在这种情况下,构建通常与源代码分开存储和归档。而Heroku的模型略有不同,它假设要部署的工件是您的存储库。差异很小,但在您的情况下,这意味着您需要提交您想要Heroku提供服务的工件到您的存储库中。

另一种思考方式是,您可以不使用 production 文件夹,并在启动服务器时运行脚本以生成 production 文件夹文件。这样可以删除 production 文件夹,并保持存储库的清洁,但每次启动服务器都需要运行此过程,这可能会变得代价高昂且不可取(Heroku 在放弃服务器之前等待启动的时间有限),但希望这能在 Heroku 和 git 关系方面提供一些明确性。

1
这是我现在正在做的事情...我创建了自己的定制构建包(请参见https://github.com/mbuchetics/heroku-buildpack-nodejs-grunt),它使用Grunt在每次部署时构建生产文件夹。它运行良好,我可以将所有生产内容保留在git存储库之外。 - mbuchetics
1
标准构建包中我所使用的另一个功能通过NPM得到支持。你可以在你的package.json文件中添加一个"postinstall"脚本,并以此方式运行任意代码。https://npmjs.org/doc/scripts.html - mikegradek

5
这种情况有点不寻常。以下是一些想法:
  • 我使用一个类似于您引用文章中的过程。
  • 我将创建一个应用程序,只需在 dev 文件夹中开始一个新的git存储库即可。
  • 然后,我建议采用类似于这个答案中所描述的部署策略:https://dev59.com/DWsz5IYBdhLWcg3wrJ6-#8058194。我对此进行了修改:

创建一个rake文件,在其中包含两个任务:rake deploy:productionrake deploy:postprocess_files。这些任务可能看起来像这样:

namespace :deploy do

  task :production do
    puts "turn on 'maintenance page' on heroku"
    system "heroku maintenance:on"

    puts "deploying to production"
    system "git push heroku-prod master"

    puts "post processing files..."
    system "heroku run rake production:postprocess_files"

    puts "take off maintenance page"
    system "heroku maintenance:off"

    puts "done"
  end 

  task :postprocess_files do
    puts "run postprocessing of files on heroku"
    ... add commands here to post process the files.
  end 
end

然后使用rake deploy:production进行部署到生产环境,而非直接使用git进行推送。这个rake文件会做以下几件事情:
  1. 设置维护页面,
  2. 推送到生产环境,
  3. 对文件进行后处理,
  4. 撤下维护页面。
请注意,你的文件中第二个rake任务包含了对文件进行后处理的命令,并且由第一个rake任务在Heroku上调用运行。
作为替代方案,你可以扩展Heroku每次部署时运行的assets:precompile任务。本质上,这就是你正在做的事情--准备要部署到生产环境的资源。

我认为这样做不会起作用。在有关一次性进程的文档中(https://devcenter.heroku.com/articles/oneoff-admin-ps)中写道:“每个dyno都有自己的短暂文件系统,不与任何其他dyno共享,并且在您断开连接时立即被丢弃。”这对于数据库脚本等工作很好,但对于修改文件系统的操作不适用。还是我漏掉了什么?另外,为什么我的情况不寻常? - mbuchetics
1
我相信你可能是正确的 - 而且,我写完这个之后意识到你正在部署node.js代码而不是rails代码。 - Kevin Bedell
我的评论是基于我假设你正在部署Rails代码,因此我认为你的情况很不寻常。但是,我对在Heroku上使用Node.js不太熟悉,所以可能并非如此。 - Kevin Bedell

2

不错!这实际上是我的项目。很高兴其他人也觉得它很有用。 - mbuchetics

2

这可能有一点令人困惑,因为:

  • 你的devproduction代表环境并且是带有生成内容的目录:
    它们不应该在版本控制系统中,而是由一个脚本自动生成,识别当前所处的环境并相应地创建正确的目录。

  • 文章中提到的devproduction(你参考的文章是关于"在Heroku上部署多个环境(同时在Github上托管代码)"),表示推广阶段,是分支

使用分支很好,只用于隔离代码变化(在这些分支中),而不是用于存储发布的生成代码。
你特定的发布管理问题(例如生成正确的交付物),应该由一个脚本来管理(可以与你的代码一起进行版本控制),并作为钩子,例如生成并部署正确的一组代码到正确的位置。


'dev' 不包含生成的内容,那是我在那里编写的源代码。'production' 是相同的,但具有优化的文件。我知道分支之间的区别。我的问题在于 Heroku 部署基于 Git 存储库。我只能部署存储库中的内容。如果不使用分支,我无法区分推送到 Github 和推送到 Heroku 的内容。 - mbuchetics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接