【问题标题】:Can I update a single source file on Heroku without recompiling the slug?我可以在不重新编译 slug 的情况下更新 Heroku 上的单个源文件吗?
【发布时间】:2012-07-09 11:24:25
【问题描述】:

我正在开发一个托管在 Heroku 上的 Rails 项目。 我想知道是否可以在不重新启动应用程序的情况下更新一个文件。

为什么。我有一个错误,但我无法追踪它。它在我的本地系统上完美运行,但它似乎在 heroku 处理的中途停止。

由于没有断点,我将状态更新分散在代码中。 (稍后删除) 但是向 Rails 应用程序添加一行代码就像是一个五分钟的过程。

  1. 更改文件
  2. 暂存文件到 git
  3. 提交文件
  4. push git(以上都挺快的)
  5. 等待 heroku 拉下应用程序,执行看起来像 gem 安装或至少 gem 更新的操作。
  6. 更改一些文件以反映本地 url
  7. 再次启动服务。

有没有办法在不运行所有其他东西的情况下推送 git?也许是要添加到推送中的特殊参数?



更令人烦恼的是,我的 git 现在有一堆我不想让我的同事看到的签到。我的目标是我自己的非生产 heroku 实例(仅测试),没有理由将所有这些尝试包含在全局源代码控制中。

【问题讨论】:

  • 要在heroku上调试问题,请尝试heroku logs。您可以看到与应用程序交互时发生的一切。
  • 日志没有这样做..他们没有给我足够的信息..这就是我分散状态更新的原因..

标签: ruby-on-rails git heroku


【解决方案1】:

XY 问题

这是经典的XY Problem。 X 是您的非工作代码; Y 是您对不存在的 Git 错误功能的搜索。

Git 的工作原理

Git 提交基本上在树级别工作,而不是文件级别。作为一个严重的过度简化,提交指向一棵树,它指向一组文件。当你推送一个提交时,你必须推送与该提交相关的所有对象,除非这些对象已经存在于接收器上。

Heroku 的工作原理

将您的 Git 存储库中的 Heroku compiles the application 转换为 slug。虽然您可以在编译期间ignore certain files,但您无法避免编译 slug。这就是平台的工作方式。

如果你有一个合理的 slug 大小,这不是问题;我的 Heroku 应用程序只需几秒钟即可编译。如果您的 slug 非常大,因此需要很长时间来编译(您声称这需要 5 分钟以上),那么如果您尝试解决“不编译”的问题,那么您手上还有另一个 XY 问题。

在 Heroku 上调试

Heroku 有很多功能和附加组件来帮助调试。这是一个简短的列表,可帮助您入门。

另见

【讨论】:

  • 五分钟有点高估了。其实也就3分钟多一点。刚好够我打开gmail。
    我不认为我有一个巨大的应用程序。 50个模型。哦..在我发布问题之前,我已经解决了 X。 X 只是一个 bug。我想解决 3 分钟,我确实在摸索。
  • 我也从未引用过 git 的缺失功能。我确切地知道(并且喜欢)git 是如何工作的。我的问题不在于 git。这是在heroku编译时,当rails(根据我读过的每一本书)不是一种编译语言并且易于调整时。从代码更改到运行 3 分钟似乎并不符合要求。但我离题了。
【解决方案2】:

这是不可能的,这是有充分理由的。当您推送到 Heroku 时,它们会生成您的应用程序的“slug”(https://devcenter.heroku.com/articles/slug-compiler)。为了提供 Heroku 提供的大规模可扩展性,这个 slug 是只读的,以便它可以在多个可能分布在许多不同物理机器上的 dyno 上旋转。这些 dyno 中的每一个都运行您的应用程序的一个单独实例,而路由网格确保对您的应用程序的请求转到正确的 dyno。

现在考虑如果这些实例中的任何一个是可写的会发生什么,如果您正在运行 5 个 dyno,那么您的应用程序将在 5 个单独的实例上运行 - 如果一个文件被写入,那么它是如何分布在您正在运行的 dyno 上的?是的,Heroku 可以考虑使用某种共享文件系统来运行应用程序,但这很复杂。通过将文件系统设为只读 (https://devcenter.heroku.com/articles/read-only-filesystem),此问题得到缓解。

如果您已经构建了一个应用程序并部署到 Heroku,但忘记使用 S3 类型的永久存储,您的应用程序将允许您将文件上传到它(通过 Ruby 世界中的 Paperclip 之类的),但上传的资产仅存在于收到它的测功机,然后在部署新代码或应用程序重新启动时将丢失,因为测功机从 slug 接收到最新代码。

如果您正在针对 Heroku 进行调试,请不要忘记您有可用的常用 git 库,git commit --amend。或者,在一个分支中工作并将其直接部署到 Heroku (git push heroku <yourbranchname>:master),然后当您隔离问题时,将您的分支重新设置为基础 (http://git-scm.com/book/en/Git-Branching-Rebasing),然后将您的分支压缩到您不再需要的任何提交上。

【讨论】:

  • 现在这是我读过的最佳答案。这很有意义。这很糟糕。吸吮的原因并不是不投票给你答案的理由。谢谢!
【解决方案3】:

这是不可能的。 heroku 的设置方式,每次推送更改时服务器都会重新启动。

【讨论】:

  • 这似乎......错了,而且反导轨。 ruby 的巨大卖点之一不是您可以快速更改事物而无需重新编译。如何关闭并重新加载所有内容然后重新启动,而不是重新编译?当然应该有办法。我会想办法的,要不就另辟蹊径。
  • 如果我们让 Rails 应用程序将文件保存在应用程序目录中会怎样?用新的代码文件覆盖代码。
  • 这听起来只是“反铁轨”,因为您不了解整个系统。不可能有非常充分的理由,我现在可以告诉你这是不可能的。您在 heroku 上的网站是只读的,这是您无法控制的。与其与这个不可能解决的问题作斗争并被跟踪,不如专注于解决最初的问题。我的 2 美分
  • 在更改模型后运行 bundle install 的一个有效(rails)理由是什么?即使它只是部分有效,我也想不出一个。
  • 这不是关于“rails”的原因,因为我们在这里讨论的不是 rails 框架,而是 托管 环境。如果您将站点托管在自己的服务器上,那么可以,您可以更改模型,之后不再运行捆绑软件。但是你在 Heroku 上托管,他们有很好的理由拥有一个只读文件系统。
【解决方案4】:

是的,你可以。

首先,列出自上次提交以来修改过的所有文件。

git status

添加您要单独提交的文件。

git add location/file_name.rb git add location/file_name2.rb ...

提交您添加到推送的文件。

git commit -m "committing files one at a time or two at a time"

现在推送

git push heroku

【讨论】:

  • 嘿伙计.. 我想你错过了这个问题。不是如何将一个文件添加到 git .. 如何将一个文件添加到 heroku。由于我只更改了一个文件,因此我可以暂存/提交所有文件。对 heroku 的推动是需要优化的部分。
  • 更正一个错字.. push...去拿一个杯子-a,回来重复。哎呀。 --- 哦,在其中一些之后去小便。
  • 我想我明白你现在想要什么了。不幸的是,你想要的是不可能的。 Heroku 收到推送后会自动安装 bundle,你无法控制 bundle 的安装方式。
  • 不太喜欢“不可能”这个词。我想我可以在我的 RAD“编译”期间做仰卧起坐 :)
猜你喜欢
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
相关资源
最近更新 更多