Tag: caching
Page Caching by Subdomain in Rails and Nginx
Posted By Ryan Stout on July 30, 2010
I'm internationalizing an app, and am splitting the locales by subdomain (es.bustaname.com, fr.bustaname.com, etc...) While other people have solved the page_caching issue with subdomains before, I couldn't find a clear explanation. All of the examples were missing one piece of information.
Controller
Add the following into your controller.
class ApplicationController < ActionController::Base # Cache pages with the subdomain def cache_page(content = nil, options = nil) path = "/#{request.host}/" path << case options when Hash url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format])) when String options else if request.path.empty? || request.path == '/' '/index' else request.path end end super(content, path) end end
This will cache each subdomain in its own directory.
To keep things clean I also move my cache directory into public/cache Just add the following to your environment.rb inside of the run block.
Rails::Initializer.run do |config| config.action_controller.page_cache_directory = RAILS_ROOT + '/public/cache/' end
Then the part everyone else seemed to miss is that this will make something like caches_page :index (note the pluralization) work, even though we defined a cache_page method. ActionController::Base has both a class and an instance version of cache_page and a class method called cache_pages. You want to use the class method cache_pages.
Nginx
Next place the following in your nginx.conf file:
# If the file exists in the public folder, send it if (-f $request_filename) { break; } # Check / files with index.html if (-f $document_root/cache/$host/$uri/index.html) { rewrite (.*) /cache/$host/$1/index.html break; } # Check the path + .html if (-f $document_root/cache/$host/$uri.html) { rewrite (.*) /cache/$host/$1.html break; } # Check directly if (-f $document_root/cache/$host/$uri) { rewrite (.*) /cache/$host/$1 break; }
This will look up cached files in /cache/$host/ and should send the files correctly. Be sure to add the nginx config before you send it to mongrel/thin/etc..
Tags: rails, caching, subdomain, cache_page, nginx
