rack-zippy is a Rack middleware for serving static gzipped assets precompiled by the Rails asset pipeline into the public/assets directory. Use it on Heroku if you want to serve the precompiled gzipped assets to gzip-capable clients with sensible caching headers.
By default, Rails + Heroku will not serve *.gz assets even though they are generated at deploy time.
rack-zippy replaces the ActionDispatch::Static
middleware used by Rails, which is not capable of serving the gzipped assets created by
the rake assets:precompile
task. rack-zippy will serve non-gzipped assets where they are not available or not supported by the
requesting client.
rack-zippy (since 2.0.0) has the same convenient directory request handling provided by ActionDispatch::Static
, which means you can take advantage of this in any rack app:
- Requests for
/
and/index
respond withpublic/index.html
if present - Requests for
/foo/
and/foo
respond with first file present out ofpublic/foo.html
,public/foo/index.html
(Same behaviour for subdirectories)
Watch the Web Dev Break podcast on rack-zippy to see how you can check if your app is currently serving uncompressed assets and how quick it is to setup rack-zippy:
Add this line to your application's Gemfile:
gem 'rack-zippy'
And then execute:
$ bundle
In config/environments/production.rb
, set config.serve_static_assets
to true
:
# Puts ActionDispatch::Static in middleware stack which we are going to replace with
# Rack::Zippy::AssetServer
config.serve_static_assets = true
Create the file config/initializers/rack_zippy.rb
and put this line in it:
Rails.application.config.middleware.swap(ActionDispatch::Static, Rack::Zippy::AssetServer)
Now run rake middleware
at the command line and make sure that Rack::Zippy::AssetServer
is near the top of the outputted list. ActionDispatch::Static should not be in the list. Nicely done, rack-zippy is now installed in your app.
Add this line to your application's Gemfile:
gem 'rack-zippy'
And then execute:
$ bundle
In config.ru
:
require 'rack-zippy'
# Set asset_root to an absolute or relative path to the directory holding your asset files
# e.g. '/path/to/my/apps/static-assets' or 'public'
asset_root = '/path/to/my/apps/public'
use Rack::Zippy::AssetServer, asset_root
Follow the installation instructions above and rack-zippy will serve any static assets, including gzipped assets, from your application's public/ directory and will respond with sensible caching headers.
max_age_fallback
, is an integer value in seconds that should be used as the max_age fallback for files served by rack-zippy that live outside the /assets
subdirectory and aren't /favicon.ico
.
A typical use for max_age_fallback
is to define how long the cache lifetime for static HTML files served by rack-zippy should be. For one of my sites I have this set to 10 minutes:
max_age_in_secs = 10*60 # 10 mins = 600 secs
use Rack::Zippy::AssetServer, asset_root, max_age_fallback: max_age_in_secs
Any files given the max_age_fallback
would have the following Cache-Control
header:
Cache-Control: public, max-age=600
Check your environment (in config/environments/) does not have serve_static_assets
set to false:
config.serve_static_assets = false # Oops! Should be set to true for rack-zippy
- Check
Gemfile
doesn't limit rack-zippy to a subset of environment groups - Run
bundle install
- Check
Gemfile.lock
contains an entry for rack-zippy
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Run tests (
rake test
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
To try a local branch of rack-zippy out as the gem dependency in a local app, configure bundler with a local gem override as follows:
In your-app/Gemfile
: edit the rack-zippy dependency to the following:
# The branch your-local-branch-name **must** exist otherwise bundler will shout obscenities at you
gem 'rack-zippy', :github => 'eliotsykes/rack-zippy', :branch => 'your-local-branch-name'
At the command line, inside your-app
, configure bundler to set a local git repo to override the one we specified in the previous step for rack-zippy:
$> bundle config --local local.rack-zippy /path/to/your/local/rack-zippy
Now when you run your-app with bundle exec
, the rack-zippy gem dependency will resolve to /path/to/your/local/rack-zippy
.
Cleanup time! When you’re finished testing, delete the local override and set your Gemfile dependency back to the original:
# At the command line:
$> bundle config --delete local.rack-zippy
# In your-app/Gemfile change rack-zippy dependency to this (or similar):
gem 'rack-zippy', '~> 9.8.7' # Replace 9.8.7 with the rack-zippy release version you want to use.
- Eliot Sykes https://eliotsykes.com
- Kieran Topping https://github.com/ktopping
- Luke Wendling https://github.com/lukewendling
- Update pre-release version to the release version in
lib/rack-zippy/version.rb
, e.g.1.0.1.pre
becomes1.0.1
- Update
CHANGELOG.md
version and date. Update Contributors inREADME.md
. - Tests pass? (
rake test
) - Build the gem (
rake build
) - Release on rubygems.org (
rake release
) - Update version to the next pre-release version in
lib/rack-zippy/version.rb
, e.g.1.0.1
becomes1.0.2.pre
. - Add new heading to
CHANGELOG
for the next pre-release - Commit and push the updated
lib/rack-zippy/version.rb
andCHANGELOG
files.