Serving precompiled assets with nginx

Viewed 31248

Is it possible to serve precompiled assets with nginx directly? Serving assets dynamically with Rails is like 20 times slower (4000 req/sec vs 200 req/sec in my virtualbox).

I guess it can be done with some rewrite rule in nginx.conf. The problem is, however, that these filenames include md5 hash of the content, so I don't really understand what can be done with this.

If its not possible I don't get the whole idea with Rails 3.1 asset pipelines. Reducing client bandwidth and page load time at the cost of x20 server load?

Any ideas?

UPD: So, I managed to setup my nginx and Rails in a way, when everything in my application is served at the speed of ~3500-4000 requests/sec.

First of all I added two virtual hosts, with one serving as a caching proxy to another and discovered that assets are served at the speed I wanted (4k). Then I connected my Rails application with memcached (nothing special so far, just one line in application.rb: ActionController::Base.cache_store = :mem_cache_store, "localhost")

Then I added things like expires_in 1.hour, :public => true if !signed_in?; to my controllers to change default caching policy of Rails content and got speed boost around 500 requests/per second for my dynamic pages (before that it was something close to 200, and it was ~50 before I ever started this all).

Now, when my nginx config files look like this:

nginx.conf:

...
proxy_cache_path  /tmp/blog keys_zone=one:8m max_size=1000m inactive=600m;
proxy_temp_path /tmp;
gzip  off;
include /opt/nginx/conf/sites-enabled/*;

sites-enabled/blog:

server {
        listen   8080;
        server_name  blindsight;

        root   /home/mike/rails/blog/public;
        rails_env production;

        # serve static content directly
        location ~* \.(ico|jpg|gif|png|swf|html)$ {
          if (-f $request_filename) {
            expires max;
            break;
          }
        }

        passenger_enabled on;

        location ~ /\.ht {
          deny  all;
        }
}

sites-enabled/main:

server {

    listen   80;
    server_name  blindsight;

    location /authorize
    {
       proxy_pass_header Cookie;
       proxy_pass_header Set-Cookie;
       proxy_pass http://127.0.0.1:8080;
    }

    location /admin
    {
       proxy_pass_header Set-Cookie;
       proxy_pass_header Cookie;
       proxy_pass http://127.0.0.1:8080;
    }

    location / {
    root /home/mike/rails/blog/public;

        # All POST requests go directly
        if ($request_method = POST) {
          proxy_pass http://127.0.0.1:8080;
          break;
        }

    proxy_redirect off;
    proxy_pass_header Cookie;
    proxy_ignore_headers Set-Cookie;
    proxy_hide_header Set-Cookie;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache one;
    proxy_cache_key blog$request_uri;
    proxy_cache_valid 200 302  5s;
    proxy_cache_valid 404      1m;
    proxy_pass http://127.0.0.1:8080;

    }

Everything is fast like a bloody lightning :) Thank you, guys.

5 Answers
Related