Boosting dragonfly with nginx
We are using a great gem: Dragonfly
Dragonfly is a framework that enables on-the-fly processing for any content type. It is especially suited to image handling. Its uses range from image thumbnails to standard attachments to on-demand text generation.
It is nice not having to deal with resizing and storing files. Putting it to use is super easy with only a few lines of code.
Spinning the hamster wheel
But when you start to load your first page, showing more than 10 images, in the browser- you’ll have some free time at your hands to brew that special coffee. Especially if your app server handles requests only sequentially - which is not uncommon on development or testing setups. Waiting for all those images getting resized over and over again becomes a bit itchy.
In the Dragonfly documentation is the recommendation:
Simply put a proxy like Rack::Cache, Varnish or Squid in front of the app and subsequent requests will be served super-quickly straight out of the cache.
But since we’re already serving our app from a nginx/passenger setup we just want to use what we have at hand already.
nginx configuration
So suppose you start off with a section similar to the following in your ngingx.conf
server {
listen 80;
server_name railsapp.example.org;
root /srv/rails/railsapp/public;
passenger_enabled on;
passenger_app_env staging;
}
We want to have control over which routes are cached. In our case everything under ’/media’. That’s why set up a second server to declare different locations having caching turned on or off.
# Defines a shared memory zone used for caching with 600minutes ttl
proxy_cache_path /tmp/nginx/cache keys_zone=one:600m;
server {
# rename the original to s.th. we'll forward to from the proxy
# should not be reachable from outside
server_name 127.0.0.1;
listen 8042;# a uniq port, too lazy to setup local host names
root /srv/rails/railsapp/public;
passenger_enabled on;
passenger_app_env staging;
}
# this is the new proxy server, reachable under the original uri,
# eventually caching requests
server {
listen 80;
server_name railsapp.mydomain.org
location /media {
auth_basic off;
# use the previously declare caching zone 'one'
proxy_cache one;
proxy_pass http://127.0.0.1:8042;
}
location /{
# fallback route without caching
proxy_pass http://127.0.0.1:8042;
}
}
And there we have it! Requests to http://railsapp.mydomain.org/media/… will be cached by nginx while all other requests http://railsapp.mydomain.org/ will directly be forwarded to the app without caching