Nginx – Caching WordPress (config sample)

The Importance of Caching WordPress » KBeezie.

Nginx Configurations

The following are the server configuratinos used for each scenario.

W3 Total Cache (no file-based caching, just memcache)

server {
	listen 80;

	server_name kbeezie.com www.kbeezie.com;
	root html/kbeezie.com;

	access_log logs/kbeezie.access.log;
	error_log logs/kbeezie.error.log;

	# Simply using try_files, tests the request uri against a file, then folder
	# then if neither can be found, the request is sent to index.php
	# this is a lot simpler than the .htaccess method of rewriting permalinks

	location / { 
		try_files $uri $uri/ /index.php; 
	}

	# Normally you do not need this if you are not using any error_page directive
	# but having it off allows WordPress to return it's own error page
	# rather than the plain Nginx screen

	fastcgi_intercept_errors off;

	# Caching the typical static files such as css, js, jpg, png and so forth
	# helps in telling the browser they can cache the content
	location ~* \.(ico|css|js|gif|jpe?g|png)$ {
		expires max;
		add_header Pragma public;
		add_header Cache-Control "public, must-revalidate, proxy-revalidate";
	}

	# I like to place my php stuff into it's own file
	# see http://kbeezie.com/view/nginx/ for more information
	include php.conf;

	# We don't really need to log favicon requests
	location = /favicon.ico { access_log off; log_not_found off; }	

	# We don't want to allow the browsers to see .hidden linux/unix files
	location ~ /\. { deny  all; access_log off; log_not_found off; }
}

WP SuperCache (file-based caching)

This configuration only differs from gzip precompression by a single line “gzip_static on;” , which would serve a gzipped file if one exists with the same name of the request. For example if the browser asked for index.html, and there exists an index.html.gz in the same folder, Nginx will serve that file to gzip-enabled browsers when the gzip static module has been enabled. Otherwise it will gzip the requested file on the fly.

server {
	listen 80;

	server_name kbeezie.com www.kbeezie.com;
	root html/kbeezie.com;

	access_log logs/kbeezie.access.log;
	error_log logs/kbeezie.error.log;

	location / { 
		# This line when enabled will use Nginx's gzip static module
		gzip_static on;

		# Disables serving gzip content to IE 6 or below
		gzip_disable        "MSIE [1-6]\.";

		# Sets the default type to text/html so that gzipped content is served
		# as html, instead of raw uninterpreted data.
		default_type text/html;

		# does the requested file exist exactly as it is? if yes, serve it and stop here
		if (-f $request_filename) { break; }

		# sets some variables to help test for the existence of a cached copy of the request
		set $supercache_file '';
		set $supercache_uri $request_uri;

		# IF the request is a post, has a query attached, or a cookie
		# then don't serve the cache (ie: users logged in, or posting comments)
		if ($request_method = POST) { set $supercache_uri ''; }
		if ($query_string) { set $supercache_uri ''; }
		if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) { 
			set $supercache_uri ''; 
		}

		# if the supercache_uri variable hasn't been blanked by this point, attempt
		# to set the name of the destination to the possible cache file
		if ($supercache_uri ~ ^(.+)$) { 
			set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html; 
		}

		# If a cache file of that name exists, serve it directly
		if (-f $document_root$supercache_file) { rewrite ^ $supercache_file break; }

		# Otherwise send the request back to index.php for further processing
		if (!-e $request_filename) { rewrite . /index.php last; }
	}

	# Normally you do not need this if you are not using any error_page directive
	# but having it off allows WordPress to return it's own error page
	# rather than the plain Nginx screen

	fastcgi_intercept_errors off;

	# Caching the typical static files such as css, js, jpg, png and so forth
	# helps in telling the browser they can cache the content
	location ~* \.(ico|css|js|gif|jpe?g|png)$ {
		expires max;
		add_header Pragma public;
		add_header Cache-Control "public, must-revalidate, proxy-revalidate";
	}

	# I like to place my php stuff into it's own file
	# see http://kbeezie.com/view/nginx/ for more information
	include php.conf;

	# We don't really need to log favicon requests
	location = /favicon.ico { access_log off; log_not_found off; }	

	# We don't want to allow the browsers to see .hidden linux/unix files
	location ~ /\. { deny  all; access_log off; log_not_found off; }
}

No Caching

The configuration for the no-cache scenario is the same as W3-Total-Cache above, since both leave PHP to handle the processing. The main difference is, on the PHP side, W3 Total Cache is caching the pages, minify results, database queries, and objects.

server {
	listen 80;

	server_name kbeezie.com www.kbeezie.com;
	root html/kbeezie.com;

	access_log logs/kbeezie.access.log;
	error_log logs/kbeezie.error.log;

	# Simply using try_files, tests the request uri against a file, then folder
	# then if neither can be found, the request is sent to index.php
	# this is a lot simpler than the .htaccess method of rewriting permalinks

	location / { 
		try_files $uri $uri/ /index.php; 
	}

	# Normally you do not need this if you are not using any error_page directive
	# but having it off allows WordPress to return it's own error page
	# rather than the plain Nginx screen

	fastcgi_intercept_errors off;

	# Caching the typical static files such as css, js, jpg, png and so forth
	# helps in telling the browser they can cache the content
	location ~* \.(ico|css|js|gif|jpe?g|png)$ {
		expires max;
		add_header Pragma public;
		add_header Cache-Control "public, must-revalidate, proxy-revalidate";
	}

	# I like to place my php stuff into it's own file
	# see http://kbeezie.com/view/nginx/ for more information
	include php.conf;

	# We don't really need to log favicon requests
	location = /favicon.ico { access_log off; log_not_found off; }	

	# We don't want to allow the browsers to see .hidden linux/unix files
	location ~ /\. { deny  all; access_log off; log_not_found off; }
}

Update: W3 Total Cache rewrite Rules for Disk (enhanced) caching

server {
	listen 80;

	server_name kbeezie.com www.kbeezie.com;
	root html/kbeezie.com;

	access_log logs/kbeezie.access.log;
	error_log logs/kbeezie.error.log;

	location / { 

		if (-f $request_filename) {
		        break;
		}

		set $pgcache "";

		if ($request_method = GET) { set $pgcache "${pgcache}D"; }

		if ($args = "") { set $pgcache "${pgcache}I"; }

		if ($http_cookie !~ (comment_author_|wordpress|wordpress_logged_in|wp-postpass_)) {
			set $pgcache "${pgcache}S";
		}
		if (-f $document_root/wp-content/w3tc/pgcache/$request_uri/_index.html) {
			set $pgcache "${pgcache}K";
		}
		if ($pgcache = "DISK") {
			rewrite ^ /wp-content/w3tc/pgcache/$request_uri/_index.html break;
		}

		if (!-e $request_filename) { rewrite . /index.php last; }
	}

	fastcgi_intercept_errors off;

	location ~* \.(ico|css|js|gif|jpe?g|png)$ {
		expires max;
		add_header Pragma public;
		add_header Cache-Control "public, must-revalidate, proxy-revalidate";
	}

	# see http://kbeezie.com/view/nginx/ for more information
	include php.conf;
	location = /favicon.ico { access_log off; log_not_found off; }	
	location ~ /\. { deny  all; access_log off; log_not_found off; }
}


This entry was posted in Uncategorized. Bookmark the permalink.

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