Skip navigation

Nginx fastcgi cache with php-fpm can be a super fast of serving WordPress Mu.

Nginx WordPress Mu FastCgi_Cache Conf Rewrites are an interesting thing to get set up because of the cookie situation. You also don’t want to have wp-admin php files cached either.

One of the problems with mu supercache is it doesn’t have very good support for Nginx. By default I think the latest version turns off the supercache portion if it cannot detect the apache mod_rewrite module or htaccess file. This means supercache is automatically turned off for nginx servers.

The Nginx fastcgi_cache is blistering fast and makes supercache redundant for Nginx users.

Usually Nginx caches a response depending on whether you have added “X-Accel-Expires: 0″ in the response with the cookie. Then you include the cookie in your key. This seemed unnecessarily complicated to set up on the wordpress side. It did require a bit of lateral thinking to get something quick n dirty up and working that avoided the above approach.

Really the only content you want nginx fastcgi cached is any permalink running off /index.php the wordpress controller for all published page requests. I couldn’t get try_files working so I just flagged the rest. This set up is for cache to expire after one day for successful 302 and 200 requests.

Step One:

The first step is in the root folder of your Mu WordPress folder make a copy of your index.php file which is the wordpress controller and call it second_index.php.

example:

/home/mu/public_html/index.php
/home/mu/public_html/second_index.php

Of course in your root wordpress folder there will be all the standard other wordpress files and folders.

Step Two:

In the main http { } area of your nginx create an area where the cached files are to be stored:

http {

fastcgi_cache_path  /var/nginx_cache levels=1:2 keys_zone=one:100m inactive=7d max_size=4g;

...
...
...
}

The above configuration sets the path to where the cache will be stored. Level's is the number of folders to use for the cache.

keys_zone is the name of the zone which you will specify in your fast_cgi parameters and 100m means that nginx will use up to 100m for to store the key values.

Inactive is the time that the cache file will stay in the cache inactive before its deleted. I've set this to a long time because I'd like to have static files cached for up to 7 days.

max_size is the size of the maximum cache size. I've set 4 gigabytes.

The cached files are stored as binary files. The key of the file is written in the binary file before the headers and the content. The file name of the cached fastcgi request is an md5 of the url. For example 'bookmarks.honewatson.com/2009/09/02/nginx-wordpress-mu-fastcgi_cache-conf-rewrites/' filename is 119a34a0e9e5817140836ffb44883df1. Using this knowledge I suppose a plugin could be written to grep through and delete the cache file if it is edited or comments are added.

Step Three:

Create a configuration that will direct all non-logged in cookie users to a location where requests are cached. For all other php files, do not cache. You don't want to fastcgi_cache files of logged in users. No php files in wp-admin are cached. Any requests of logged in users are sent to second_index.php which is not cached. They can see regularly updated comments. You could also set it up so the cache time is much lower for logged in users. Maybe 5 minutes. I'll include a second configuration down the bottom for this.

This means you get far greater control than you would with supercache.

So here is something that is working for me:

location / {
            	root   /home/mu/public_html;
            	index index.php;
		if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
			error_page       404 = /second_index.php?q=$uri;
			 
		}
	    	error_page       404 = /index.php?q=$uri;
}


location ~ /index\.php.*$ {
	fastcgi_cache_key $host$request_uri;
	fastcgi_cache_valid 200 302 1d;
	fastcgi_cache_valid 301 7d;
	fastcgi_cache_valid any 5m;
	fastcgi_cache_use_stale off;
	fastcgi_cache one;  
	fastcgi_ignore_headers  Cache-Control  Expires;
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}

location ~ \.php$ {
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}

Second configuration:

  1. Cache any 200 or 302 published content requests from anonymous users for 1 day.
  2. Cache any 200 or 302 published content requests for logged in users for 5 minutes.
  3. Don't cache any other php files.

location / {
            	root   /home/mu/public_html;
            	index index.php;
		if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
			error_page       404 = /second_index.php?q=$uri;
			 
		}
	    	error_page       404 = /index.php?q=$uri;
}


location ~ /index\.php.*$ {
	fastcgi_cache_key $host$request_uri;
	fastcgi_cache_valid 200 302 1d;
	fastcgi_cache_valid 301 7d;
	fastcgi_cache_valid any 5m;
	fastcgi_cache_use_stale off;
	fastcgi_cache one;  
	fastcgi_ignore_headers  Cache-Control  Expires;
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}

location ~ /second_index\.php.*$ {
	fastcgi_cache_key $host$request_uri;
	fastcgi_cache_valid 200 302 5m;
	fastcgi_cache_valid 301 1d;
	fastcgi_cache_valid any 5m;
	fastcgi_cache_use_stale off;
	fastcgi_cache one;  
	fastcgi_ignore_headers  Cache-Control  Expires;
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}


location ~ \.php$ {
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}

Third configuration:

  1. Cache uploaded files for 7 days - slip this extra configuration in before the all other php files location.



location ~ /wp-content/blogs\.php.*$ {
access_log  /nginx_logs/muimagesphp_cache.access.log small_php;
fastcgi_read_timeout 10;
fastcgi_cache_key $host$request_uri;
	fastcgi_cache_valid 200 302 7d;
	fastcgi_cache_valid 301 7d;
       fastcgi_cache_valid 504 1s;
	fastcgi_cache_valid any 5m;
	fastcgi_cache_use_stale off;
	fastcgi_cache one;  
	fastcgi_ignore_headers  Cache-Control  Expires;
	fastcgi_pass   127.0.0.1:8084;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME /home/mu/public_html$fastcgi_script_name;
	include        /usr/local/nginx/conf/fastcgi_params;
}


location ~ \.php$ {
...
... etc

}


About these ads

3 Comments

  1. Does this mean that i dont need supercache at all?

    I have been reading around and feel that nginx + php fastcgi is the way to go for wpmu sites. Thanks in part to a lot of your contributions on the wordpress forums.

    I was looking at slides on wordpress scalability here http://joseph.randomnetworks.com/archives/2008/09/01/slides-from-wordpress-performance-scalability/ Do you think that turning on APC with PHP fastCGI on Nginx for wpmu without supercache will get me a steady running site?

    Appreciate the help.

    • If you use nginx fastcgi_cache with the correct configuration you do not need the supercache part of supercache. You can still use wp-cache however a batcache + nginx fastcgi_cache might be the best solution.

  2. So far, your posts here and on various forums are the best on caching and WordPress that I’ve seen! Kudos! I’m having a problem with WordPress MU and Nginx. I’m wondering if you have any experience with the new try_files directive and WordPress (or WordPress MU). I’ve got most things working. I cannot seem to figure out how to get these links to work using that approach:

    http://test.com/test/wp-admin/

    I think I know why. My location block used to start like this:

    location /wp-admin

    now it looks like this:

    location ~* ^/.*(/wp-admin/.*)$

    I can see the wp-admin page for the first blog, the second blog appears messed up – as if javascript was not properly downloaded. Do you have any suggestions?


3 Trackbacks/Pingbacks

  1. By » Enlaces para optimizar WordPress MU on 12 Sep 2009 at 4:20 pm

    [...] Nginx WordPress Mu FastCgi_Cache Conf Rewrites, por Hone Watson. Si utilizas Nginx como servidor web y tienes problemas para activar el full-mode [...]

  2. [...] Batcache and W3 Total Cache are both interesting but I’ve personally found the best caching system is to use a combination of Nginx SSI Memcached and Nginx Fastcgi cache. [...]

  3. By Nginx fastcgi_cache caveat | Tony Kwon on 01 Dec 2010 at 8:42 pm

    [...] Nginx WordPress Mu FastCgi_Cache Conf Rewrites [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: