7
votes

I've been running a Rails 3.1 app on Heroku Cedar Stack for a couple of months now. I'm using Rack::Deflater middleware to gzip my content and achieve this by

config.middleware.insert_before ActionDispatch::Static, Rack::Deflater

in my staging.rb file.

However, since last week, I get the following error when deploying to Heroku

Running: rake assets:precompile
   rake aborted!
   No such middleware to insert before: ActionDispatch::Static

However, running rake middleware still returns

use Rack::Cache
use Rack::Deflater
use ActionDispatch::Static
use Rack::Lock

And content served were still gzipped. However, assets were not compiled(minified) as pre-compilation failed. A manual rake precompile::asets also does not help.

So, I'm assuming ActionDispatch::Static is not available during pre-compilation of assets. So I tried to insert Rack::Deflater before Rack::Lock and now my assets are compiled without any error message but content served is not gzipped.

So, what do I need to do, to both gzip and compile my assets? What am I missing? Thanks.

2

2 Answers

5
votes

Just a heads up Rack::Deflater is already used by Rails 3.1 so you don't need to manually do this.

BUT, to answer your problem here, I would assume that your production.rb has config.serve_static_assets = false set.

the ActionDispatch::Static middleware is only used when serve_static_assets is set to true. Heroku actually injects this config to override whatever you set anyway (see the Injecting rails3_serve_static_assets log message when you deploy), but I'm not sure at what stage in the deploy this happens.

So it's likely that you don't have static asset serving enabled when the assets:precompile runs (note this is just a guess, I'm not on Rails 3.1 yet so I could be wrong)

I would recommend against membLoper's suggestion of adding it manually in your rackup file:

  1. it's not needed as explained above
  2. your middleware that is relevant to your app should really be injected as you had originally tried in your application.rb
3
votes

I still dont understand why Heroku does not recognize ActionDispatch::Static during pre-compilation of assets. However, Heroku folks did suggest a workaround to this issue.

The Rack::Deflater middleware needs to inserted in config.ru file rather than environment files. Something like,

require ::File.expand_path('../config/environment',  __FILE__)
# Middleware to gzip content
use Rack::Deflater
run MyApplication

This way, it does not interfere with assets pre-compilation and still gzips the content being served.

Any resource on how config.ru works and where Rack::Deflater now resides is very welcome.