由 Unicorn 提供服务的 Rails 会为预编译资产生成错误的指纹

由 Unicorn 提供服务的 Rails 会为预编译资产生成错误的指纹

我有一个生产服务器,其中 nginx -> unicorn -> rails。我预编译了资产,将资产放入 public/assets 中,并在文件名后附加指纹(哈希值)。但是,当请求网页时,对 application.css 和 application.js 资产的引用将具有错误的指纹。例如,rails 帮助程序 stylesheet_link_tag 将生成服务器上 public/assets 中不存在的文件名,因为请求的指纹与预编译的指纹不匹配。图像资产工作正常(指纹匹配)。

为了解决这个问题,我在本地机器上预编译了资产,指纹与服务器上的预编译指纹相匹配。此外,在生产模式下使用 webrick 本地运行时,一切正常。然后我尝试在我的服务器上运行 webrick,成功了,这让我认为 unicorn 是问题的根源。

我通过使用 --no-default-middleware(或 -N)选项启动 unicorn 解决了这个问题,这使得 unicorn 在预编译资产方面表现得如预期一样。我的理解是,这告诉 unicorn 不要加载一组默认的 Rack 中间件,否则它会加载。但是,我不太明白为什么这能解决问题,或者首先出了什么问题。到底是怎么回事?

一些细节:Ubuntu 12.04、Rails 4.0.1、Ruby 2.1.0、带有第三方主题的 bootstrap 3.0

更新:

我不认为这是 nginx 的问题,原因是当我从浏览器请求页面,然后查看源代码时,application.css 文件的文件名有一个指纹,因此它实际上看起来像 application-3855b1928b94aa5bff5e1dac1aa56882.css。这与我服务器上文件的真实指纹不匹配。我确信服务器上的指纹是正确的,因为我在本地开发机器上获得了相同的指纹。因此,客户端正在加载网页,然后向服务器请求 .css 文件……nginx 收到了该请求,但找不到 .css 文件,因为它实际上并不存在,因此 nginx 的行为符合预期。

指纹生成两次:一次是在我预编译资产时,这工作正常(非常确定),并且没有 unicorn 参与。第二次是在 unicorn worker 上下文中的 rails 看到 stylesheet_link_tag 助手并动态计算指纹时(我认为这是它正在做的事情),由于某种原因,这会生成错误的指纹。如果我在完全相同的服务器上用 webrick 替换 unicorn,也会发生同样的过程,但在这种情况下指纹匹配。如果我使用 -N 标志启动 unicorn,指纹会匹配,但我不知道为什么这会产生差异,也不知道为什么似乎没有其他人必须这样做。

答案1

在 rails 4 中你需要做以下更改

config.assets.compile = true
config.assets.precompile =  ['*.js', '*.css', '*.css.erb'] 

这对我有用。使用以下命令预编译资产

RAILS_ENV=production bundle exec rake assets:precompile

https://stackoverflow.com/questions/18700219/rails-4-assets-not-loading-in-production

相关内容