Running WordPress On Nginx (LEMP) On Debian Squeeze/Ubuntu 11.04 - Page 2

Want to support HowtoForge? Become a subscriber!
 
Submitted by falko (Contact Author) (Forums) on Tue, 2011-08-30 18:08. ::

4 Caching With WP Super Cache Or W3 Total Cache

This chapter deals with configuring nginx with WP Super Cache or nginx with W3Total Cache. Please do not use both plugins at the same time (I'm not sure if it is possible to use both at the same time - I didn't try because it doesn't make sense) - opt for one plugin and then follow the appropriate chapter here.

 

4.1 WP Super Cache

After you have installed and enabled WP Super Cache from your WordPress admin interface, go to Settings > WP Super Cache and then to the Advanced tab.

Enable caching by checking Cache hits to this website for quick access and Use mod_rewrite to serve cache files - this option is very important as it allows us to completely bypass the PHP backend and directly serve cached pages from the file system cache which makes your site very fast, especially because nginx is lightning fast at serving static files. I will show you how to configure nginx to do the necessary rewrites in a moment.

The other settings are up to you, although I recommend the following settings:

Further down the page, make sure you have

wp-.*\.php
index\.php

in the Add here strings (not a filename) that forces a page not to be cached field:

That's it for the WP Super Cache configuration. Now we must reconfigure our nginx vhost. I've come up with two solutions that both work equally well:

 

4.1.1 First Possible Nginx Configuration

My first solution is as follows:

Open /etc/nginx/sites-available/www.example.com.vhost...

vi /etc/nginx/sites-available/www.example.com.vhost

... and replace

[...]
       location / {
                try_files $uri $uri/ /index.php?$args;
       }
[...]

... with:

[...]
       location @nocache {
                try_files $uri $uri/ /index.php?$args;
       }
[...]

Then add the following new location / { } section:

[...]
       location / {
                # WP Super Cache rules.
                # Enable detection of the .gz extension for statically compressed content.
                # Comment out this line if static gzip support is not compiled into nginx.
                gzip_static on;
                # If this is a POST request, pass the request onto WordPress.
                if ($request_method = POST) {
                   return 405;
                }
                # If there is a query string, serve the uncached version.
                if ($query_string) {
                   return 405;
                }
                # Logged in users and those who have posted a comment get the non-cached version.
                if ($http_cookie ~* comment_author_|wordpress_logged_in|wp-postpass_) {
                   return 405;
                }
                # Mobile browsers get the non-cached version.
                # Wastes CPU cycles if there isn't a mobile browser WP theme for the site.
                if ($http_x_wap_profile) {
                   return 405;
                }
                if ($http_profile) {
                   return 405;
                }
                if ($http_user_agent ~* (2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800)) {
                   return 405;
                }
                if ($http_user_agent ~* (w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-)) {
                   return 405;
                }
                error_page 405 @nocache;
                add_header Expires "Sun, 19 Nov 1978 05:00:00 GMT";
                add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
                try_files /wp-content/cache/supercache/${http_host}${uri}index.html @nocache;
       }
[...]

The complete file looks as follows:

server {
       listen 80;
       server_name www.example.com example.com;
       root /var/www/www.example.com/web;
       if ($http_host != "www.example.com") {
                 rewrite ^ http://www.example.com$request_uri permanent;
       }
       index index.php index.html;
       location = /favicon.ico {
                log_not_found off;
                access_log off;
       }
       location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
       }
       # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
       location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
       }
       location / {
                # WP Super Cache rules.
                # Enable detection of the .gz extension for statically compressed content.
                # Comment out this line if static gzip support is not compiled into nginx.
                gzip_static on;
                # If this is a POST request, pass the request onto WordPress.
                if ($request_method = POST) {
                   return 405;
                }
                # If there is a query string, serve the uncached version.
                if ($query_string) {
                   return 405;
                }
                # Logged in users and those who have posted a comment get the non-cached version.
                if ($http_cookie ~* comment_author_|wordpress_logged_in|wp-postpass_) {
                   return 405;
                }
                # Mobile browsers get the non-cached version.
                # Wastes CPU cycles if there isn't a mobile browser WP theme for the site.
                if ($http_x_wap_profile) {
                   return 405;
                }
                if ($http_profile) {
                   return 405;
                }
                if ($http_user_agent ~* (2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800)) {
                   return 405;
                }
                if ($http_user_agent ~* (w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-)) {
                   return 405;
                }
                error_page 405 @nocache;
                add_header Expires "Sun, 19 Nov 1978 05:00:00 GMT";
                add_header Cache-Control "must-revalidate, post-check=0, pre-check=0";
                try_files /wp-content/cache/supercache/${http_host}${uri}index.html @nocache;
       }
       location @nocache {
                try_files $uri $uri/ /index.php?$args;
       }
       # Add trailing slash to */wp-admin requests.
       rewrite /wp-admin$ $scheme://$host$uri/ permanent;
       location ~*  \.(jpg|jpeg|png|gif|css|js|ico)$ {
                expires max;
                log_not_found off;
       }
       location ~ \.php$ {
                try_files $uri =404;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       }
}

Then reload nginx:

/etc/init.d/nginx reload

 

4.1.2 Second Possible Nginx Configuration

The second possible solution is that we create the file /var/www/www.example.com/nginx/wordpress-wp-super-cache.conf with the necessary rewrite rules as follows:

mkdir /var/www/www.example.com/nginx
vi /var/www/www.example.com/nginx/wordpress-wp-super-cache.conf

# WP Super Cache rules.
# Enable detection of the .gz extension for statically compressed content.
# Comment out this line if static gzip support is not compiled into nginx.
gzip_static on;
set $supercacheuri "";
set $supercachefile "$document_root/wp-content/cache/supercache/${http_host}${uri}index.html";
if (-e $supercachefile) {
    set $supercacheuri "/wp-content/cache/supercache/${http_host}${uri}index.html";
}
# If this is a POST request, pass the request onto WordPress.
if ($request_method = POST) {
    set $supercacheuri "";
}
# If there is a query string, serve the uncached version.
if ($query_string) {
    set $supercacheuri "";
}
# Logged in users and those who have posted a comment get the non-cached version.
if ($http_cookie ~* comment_author_|wordpress_logged_in|wp-postpass_) {
    set $supercacheuri "";
}
# Mobile browsers get the non-cached version.
# Wastes CPU cycles if there isn't a mobile browser WP theme for the site.
if ($http_x_wap_profile) {
    set $supercacheuri "";
}
if ($http_profile) {
    set $supercacheuri "";
}
if ($http_user_agent ~* (2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800)) {
    set $supercacheuri "";
}
if ($http_user_agent ~* (w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-)) {
    set $supercacheuri "";
}
# Stop processing if the supercache file is valid.
if ($supercacheuri) {
    rewrite ^ $supercacheuri break;
}

Then include that file by adding the line include /var/www/www.example.com/nginx/wordpress-wp-super-cache.conf; to /etc/nginx/sites-available/www.example.com.vhost:

vi /etc/nginx/sites-available/www.example.com.vhost

server {
       listen 80;
       server_name www.example.com example.com;
       root /var/www/www.example.com/web;
       if ($http_host != "www.example.com") {
                 rewrite ^ http://www.example.com$request_uri permanent;
       }
       index index.php index.html;
       location = /favicon.ico {
                log_not_found off;
                access_log off;
       }
       location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
       }
       # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
       location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
       }
       location / {
                try_files $uri $uri/ /index.php?$args;
       }
       # Add trailing slash to */wp-admin requests.
       rewrite /wp-admin$ $scheme://$host$uri/ permanent;
       location ~*  \.(jpg|jpeg|png|gif|css|js|ico)$ {
                expires max;
                log_not_found off;
       }
	   
	   include /var/www/www.example.com/nginx/wordpress-wp-super-cache.conf;
       location ~ \.php$ {
                try_files $uri =404;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       }
}

Reload nginx:

/etc/init.d/nginx reload

 

4.2 W3 Total Cache

The good thing about W3 Total Cache is that it comes with nginx support already!

It is important the W3 Total Cache has write permissions for the document root /var/www/www.example.com/web because it tries to create the file /var/www/www.example.com/web/nginx.conf automatically which contains the necessary rewrite rules for nginx. (That's why we ran

chown -R www-data:www-data /var/www/www.example.com/web

in chapter 3.)

If you are sure that your permissions are ok so that W3 Total Cache can write to your document root, you can proceed. After you have installed and enable W3 Total Cache, go to Performance in the WordPress admin interface. You will see the following error message that you can ignore (I think this is a little bug in W3 Total Cache because it correctly detects nginx instead of Apache and tries to write an nginx.conf file, but still it displays this error message):

It appears Page Cache URL rewriting is not working. If using apache, verify that the server configuration allows .htaccess or if using nginx verify all configuration files are included in the configuration.

In fact, the Page Cache does work, I tested it.

Scroll down and activate the following caches: Page Cache, (don't enable Minify)...

... Database Cache, Object Cache,...

..., and Browser Cache, then save your settings. Afterwards, W3 Total cache creates/updates the file /var/www/www.example.com/web/nginx.conf.

All we have to do now is include that file in our vhost and make sure that a user cannot directly access the file through a browser. Therefore we open /etc/nginx/sites-available/www.example.com.vhost...

vi /etc/nginx/sites-available/www.example.com.vhost

... and add the following part:

[...]
       include /var/www/www.example.com/web/nginx.conf;
       location ~ /nginx.conf {
                deny all;
                access_log off;
                log_not_found off;
       }
[...]

The complete vhost configuration looks as follows:

server {
       listen 80;
       server_name www.example.com example.com;
       root /var/www/www.example.com/web;
       if ($http_host != "www.example.com") {
                 rewrite ^ http://www.example.com$request_uri permanent;
       }
       index index.php index.html;
       location = /favicon.ico {
                log_not_found off;
                access_log off;
       }
       location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
       }
       # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
       location ~ /\. {
                deny all;
                access_log off;
                log_not_found off;
       }
       location / {
                try_files $uri $uri/ /index.php?$args;
       }
       include /var/www/www.example.com/web/nginx.conf;
       location ~ /nginx.conf {
                deny all;
                access_log off;
                log_not_found off;
       }
       # Add trailing slash to */wp-admin requests.
       rewrite /wp-admin$ $scheme://$host$uri/ permanent;
       location ~*  \.(jpg|jpeg|png|gif|css|js|ico)$ {
                expires max;
                log_not_found off;
       }
       location ~ \.php$ {
                try_files $uri =404;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       }
}

Reload nginx afterwards:

/etc/init.d/nginx reload

 

5 Links

 

About The Author

Falko Timme is the owner of Boost Your Site mit Timme Hosting - ultra-schnelles nginx-WebhostingTimme Hosting (ultra-fast nginx web hosting). He is the lead maintainer of HowtoForge (since 2005) and one of the core developers of ISPConfig (since 2000). He has also contributed to the O'Reilly book "Linux System Administration".


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.