Tag Archive - cache

Nginx, WordPress, WP Super Cache and Mobile Theme

I’ve previously written about how to configure WP Super Cache to work with Nginx.

When using a mobile theme plugin, WPtouch in my case, the serving of static files (WP Super Cache does that in rewrite mode) needs to be disabled for mobile requests. Otherwise you could end up with static files (containing your standard theme) being served to mobile users.

WP Super Cache also needs to be configured with Mobile device support to prevent mobile visitors from trigger static files to be generated. So start by enable that feature in the advanced settings for WP Super Cache.

Then change the Nginx rewrite rules to the following.

# Return existing files
if (-f $request_filename) {
        break;
}

set $supercache_file '';
set $supercache_uri $request_uri;

if ($request_method = POST) {
        set $supercache_uri '';
}

# Bypass cache for requests containing a query string
if ($query_string) {
        set $supercache_uri '';
}

if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
        set $supercache_uri '';
}

# Bypass cache for mobile users
if ($http_user_agent ~* "(Android|CUPCAKE|bada|blackberry 9800|blackberry9500|blackberry9520|blackberry9530|blackberry9550|dream|iPhone|iPod|incognito|s8000|webOS|webmate)") {
        set $supercache_uri '';
}

# Specify the cache file
if ($supercache_uri ~ ^(.+)$) {
        set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
}

# Serve the cache file, if it exists
if (-f $document_root$supercache_file) {
        rewrite ^(.*)$ $supercache_file break;
}

# Everything else goes to index.php
if (!-e $request_filename) {
        rewrite . /index.php last;
}

The user agents listed above are the same ones WPtouch sends the mobile theme to. If you change the settings in WPtouch, change the rewrite rules as well.

Reload Nginx.

Install, enable and configure the WPtouch plugin, and that should be it. I’ve been using this setup for about a month now without any problems, let me know if you run into something.

CloudFront with origin pull and WP Super Cache

Using AWS CloudFront as a CDN (content delivery network) for your site can be a good way of speeding things up.

CloudFront has support for origin pull (this way, there’s no need to sync files, they’re fetched on demand from the web server). Configuring this can be a bit tricky, since the AWS web interface only supports AWS S3 buckets to be configured as backends.

To get a distribution with origin pull up and running we need to do it manually. I’m assuming you’re working on some kind of unix/linux system (OS X for example). First of all, you need an AWS account with CloudFront. If you don’t already have one, get it here.

Create a file named .aws-secrets containing your AWS Access Keys (these can be found in the AWS Portal under Account -> Security Credentials), in the following format.

%awsSecretAccessKeys = (
    "my-aws-account" => {
        id => "ID goes here",
        key => "Key goes here",
    },
);

Create a XML file containing the settings of the new distribution, name it cf.xml.

<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
<CustomOrigin>
    <DNSName>example.com</DNSName>
    <HTTPPort>80</HTTPPort>
    <OriginProtocolPolicy>http-only</OriginProtocolPolicy>
</CustomOrigin>
<CallerReference>1234</CallerReference>
<CNAME>cdn.example.com</CNAME>
<Comment/>
<Enabled>true</Enabled>
<DefaultRootObject>index.php</DefaultRootObject>
</DistributionConfig>

Replace example.com with your domain. CNAMES can also be added and changed later via the AWS Management Console.

Download the cfcurl.pl script.

Execute the following command.

cfcurl.pl --keyname my-aws-account -- -X POST -H "Content-Type: text/xml; charset=UTF-8" --upload-file cf.xml https://cloudfront.amazonaws.com/2010-11-01/distribution

Point the cdn domain you entered in the cf.xml file to the domain returned in the block with a CNAME. You can also get this name from the AWS Management Console.

If you don’t already have WP Super Cache installed, install it now. Then go to Settings -> WP Super Cache -> CDN and enter the cdn domain name as the Off-site URL and check Enable CDN Support.

Clean out the existing cache and visit your front page, content like css, javascript and images should now be loaded from the CDN.

Precaching with WP Super Cache

Since earlier this year, the WordPress cache plugin WP Super Cache supports precaching. This enables the ability to create static content of your entire site.

For a busy site this is probably not needed, since user activity triggers generation of static files. But for a smaller sites (like this one) it could help speed things up for both visitors and search engines, which in turn could improve your page rank.

I activated precache around midnight yesterday, this performance graph shows quite well the difference in loading times.

Running a DNS cache with djbdns

This is how to run a DNS cache with djbdns, I will be doing this on Ubunut 9.10. Start by installing djbdns.

# aptitude install djbdns

Create system accounts.

# useradd -d /etc/dnscache -s /bin/false dnscache
# useradd -d /etc/dnscache -s /bin/false dnslog

Now create the configuration directory for dnscache.

# dnscache-conf dnscache dnslog /etc/dnscache 10.227.66.66

10.227.66.66 is our IP address we’ll be running the daemon on.

Add the IP addresses that are allowed to query the server. The following will allow the entire 10.0.0.0/16 network to query the server.

# touch /etc/dnscache/root/ip/10

Create a symbolic link so that svscan will start dnscache, and check that it is running. svscan is a part of daemontools, which is a part of the djbdns package. It is used to start and monitor services.

# ln -s /etc/dnscache /etc/service/dnscache
# ps aux |grep dnscache
root      1992  0.0  0.0   1560   332 pts/0    S    18:02   0:00 supervise dnscache
dnscache  1993  0.0  0.0   3000  1620 pts/0    S    18:02   0:00 /usr/bin/dnscache

Make a test query, verify that everything is working.

# dig @10.227.66.66 poller.se
; <<>> DiG 9.6.1-P1 <<>> @10.227.66.66 poller.se
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63009
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;poller.se.			IN	A

;; ANSWER SECTION:
poller.se.		3600	IN	A	83.218.95.132

;; Query time: 554 msec
;; SERVER: 10.227.66.66#53(10.227.66.66)
;; WHEN: Fri Jan 15 18:03:00 2010
;; MSG SIZE  rcvd: 43

WP Super Cache with Nginx

WP Super Cache is a very good tool for speeding up your WordPress installation while at the same time reducing server load. However, WP Super Cache uses mod_rewrite to handle requests, which is not compatible with Nginx. For it to work with Nginx we need to create a few rewrite rules in the server config file.

In my example I have Nginx installed with php5 running as FastCGI, configured like this.

This requires permalinks to be used, request containing query strings will not be served cached content. The following rules are added to the location / { } block in the Nginx config file for that virtual host. This assumes WordPress is not installed in a sub folder.

# Return existing files
if (-f $request_filename) {
        break;
}

set $supercache_file '';
set $supercache_uri $request_uri;

if ($request_method = POST) {
        set $supercache_uri '';
}

# Bypass cache for requests containing a query string
if ($query_string) {
        set $supercache_uri '';
}

if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
        set $supercache_uri '';
}

# Specify the cache file
if ($supercache_uri ~ ^(.+)$) {
        set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
}

# Serve the cache file, if it exists
if (-f $document_root$supercache_file) {
        rewrite ^(.*)$ $supercache_file break;
}

# Everything else goes to index.php
if (!-e $request_filename) {
        rewrite . /index.php last;
}