生产环境中的rack-zippy和选项-d不提供静态资产

我这里有一个非常奇怪的问题。 我在我的rails应用程序中使用rack-zippy gem,如果我在没有预编译资产的development环境中启动它,它就像一个魅力。 使用-d param而不使用。

在生产模式(相同的机器,相同的项目,相同的目录,相同的gem),它也有效。 但是,如果我使用-d param( bundle exec rails server -d )启动它来守护服务器,则不会提供预编译的资产。 可以用thinwebrick重现,但不与unicorn

日志说:

 ActionController::RoutingError (No route matches [GET] "/assets/application-b9b75968aed42128cfd75fb78df1e4d1.js"): 

但:

 $ l public/assets/application-b9b75968aed42128cfd75fb78df1e4d1.js -rw-r--r-- 1 public/assets/application-b9b75968aed42128cfd75fb78df1e4d1.js 

来自config / environments / production.rb:

 config.serve_static_assets = true 

来自config / application.rb:

 config.middleware.swap(ActionDispatch::Static, Rack::Zippy::AssetServer) 

和:

 $ rake middleware use Rack::Sendfile use Rack::Zippy::AssetServer (...) 

我现在有些困惑。 有任何想法吗?

哎呀,我从来没有遇到过这个,但我会告诉你我的直觉,也许你可以在这里得到一些。 (感谢您在Github问题跟踪器上报告)。

所以独角兽是好的,但是薄而且我们不是,mmmm。

我的猜测是守护进程为thin和webrick使用的工作目录不是Rails.root。 您可能想尝试在rack-zippy中调试此行,以查看正在搜索资产文件的路径: https : //github.com/eliotsykes/rack-zippy/blob/master/lib/rack-zippy.rb #L87

rack-zippy从版本1.1.0开始(如果你使用的是最新的Gem,你可能正在使用它)传递所有请求,它无法找到一个文件,可用于剩余的中间件堆栈。

在开发+守护进程模式下,rack-zippy会将请求传递到资产管道,所以我认为我们可以假设资产管道在守护进程模式下没有问题。

在生产+守护进程模式下,资产管道可能已禁用(如您所愿),如果找不到资产文件,rack-zippy将向前传递请求(如果工作目录是不是Rails.root),然后剩下的中间件会给你看到的路由错误。

如果您在生产中启用了资产管道(非常不推荐),那么我预计路由错误会消失,而rack-zippy将不会做任何有用的事情。

对不起,我没有更坚实的东西继续下去。

在下一版本的rack-zippy中发布修复程序之前,要解决此问题,您可以使用此行(可能在config/application.rbconfig/initializers/rack_zippy.rb ):

 Rails.application.config.middleware.swap(ActionDispatch::Static, Rack::Zippy::AssetServer) 

替换为:

 # Rails.public_path as last argument here gets passed into the Rack::Zippy::AssetServer # constructor to override the default asset_root argument value. Rails.application.config.middleware.swap(ActionDispatch::Static, Rack::Zippy::AssetServer, Rails.public_path)