NGINX Reverse Proxy W3 Total Cache!!

I recently wrote a post about how I set up NGINX as a reverse proxy.

In need of a caching solution, I decided to use W3 total cache as it supports NGINX. The problem was that the server that was handling the requests was Apache, so it only created htaccess rules. I finally managed to create the NGINX rules I want.

What they do

These rules will really boost the performance of your site. If a user requests a cached page, NGINX will handle it without even sending the request to Apache, and NGINX is best with static content. This also has the advantage of if your Apache server crashes or gets too slow, requests that have been cached can bypass that, so you’re site will still be somewhat online.

The config

Simply install W3 Total Cache, and do whatever you want, just be sure to choose Disk: Enhanced for page caching. It will automatically create the htaccess rules for you, and here are the NGINX rules:

# BEGIN W3TC Page Cache core
set $w3tc_rewrite 1;
if ($request_method = POST) {
    set $w3tc_rewrite 0;
}
if ($query_string != "") {
    set $w3tc_rewrite 0;
}
if ($request_uri !~ \/$) {
    set $w3tc_rewrite 0;
}
if ($http_cookie ~* "(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle)") {
    set $w3tc_rewrite 0;
}
set $w3tc_preview "";
if ($http_cookie ~* "(w3tc_preview)") {
    set $w3tc_preview _preview;
}
set $w3tc_ssl "";
if ($scheme = https) {
    set $w3tc_ssl _ssl;
}
if ($http_x_forwarded_proto = 'https') {
    set $w3tc_ssl _ssl;
}
set $w3tc_enc "";
if ($http_accept_encoding ~ gzip) {
    set $w3tc_enc _gzip;
}
set $w3tc_ext "";
if (-f "$document_root/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_ssl$w3tc_preview.html$w3tc_enc") {
    set $w3tc_ext .html;
}
if (-f "$document_root/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_ssl$w3tc_preview.xml$w3tc_enc") {
    set $w3tc_ext .xml;
}
if ($w3tc_ext = "") {
  set $w3tc_rewrite 0;
}
if ($w3tc_rewrite = 1) {
    rewrite .* "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_ssl$w3tc_preview$w3tc_ext$w3tc_enc" last;
}
# END W3TC Page Cache core
# BEGIN W3TC Page Cache cache
location ~ /wp-content/cache/page_enhanced.*html$ {
    expires modified 3600s;
    add_header X-Powered-By "W3 Total Cache/0.9.6";
    add_header Vary "Accept-Encoding, Cookie";
    add_header Pragma "public";
    add_header Cache-Control "max-age=3600, public";
}
location ~ /wp-content/cache/page_enhanced.*gzip$ {
    gzip off;
    types {
        text/xml xml_gzip;
    }
    default_type text/html;
    expires modified 3600s;
    add_header X-Powered-By "W3 Total Cache/0.9.6";
    add_header Vary "Accept-Encoding, Cookie";
    add_header Pragma "public";
    add_header Cache-Control "max-age=3600, public";
    add_header Content-Encoding gzip;
}
# END W3TC Page Cache cache
#Browser Cache
#location ~ (robots\.txt|[a-z0-9_\-]*sitemap[a-z0-9_\-]*\.(xml|xsl|html)(\.gz)?|([a-z0-9_\-]+)?sitemap(_index)?(-)?([0-9]*)?\.(xml(\.gz)?|xsl)$|) {
#    #try_files $uri $uri/ $uri.html /index.php?$args;
#}
location ~ \.(css|htc|less|js|js2|js3|js4)$ {
    expires 604800s;
    etag on;
    if_modified_since exact;
    add_header Pragma "public";
    add_header Cache-Control "max-age=604800, public";
    add_header X-Powered-By "W3 Total Cache/0.9.6";
}
location ~ \.(html|htm|rtf|rtx|svg|txt|xsd)$ {
    expires 3600s;
    etag on;
    if_modified_since exact;
    add_header Pragma "public";
    add_header Cache-Control "max-age=3600, public";
    add_header X-Powered-By "W3 Total Cache/0.9.6";
}
location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip)$ {
    expires 604800s;
    etag on;
    if_modified_since exact;
    add_header Pragma "public";
    add_header Cache-Control "max-age=604800, public";
    add_header X-Powered-By "W3 Total Cache/0.9.6";
    add_header Link "<$scheme://$host$uri>; rel=\"canonical\"";
    if ($request_uri ~ ^[^?]*\.(ttf|ttc|otf|eot|woff|woff2|font.css)(\?|$)) {
        add_header Link "<$scheme://$host$uri>; rel=\"canonical\"";
        add_header Pragma "public";
        add_header Cache-Control "max-age=604800, public";
        add_header X-Powered-By "W3 Total Cache/0.9.6";
        add_header Access-Control-Allow-Origin "*";
    }
}
location ~ \.(bmp|class|doc|docx|eot|exe|ico|webp|json|mdb|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|pot|pps|ppt|pptx|svg|svgz|swf|tif|tiff|ttf|ttc|_ttf|wav|wri|woff|woff2|xla|xls|xlsx|xlt|xlw)$ {
    etag off;
    if_modified_since off;
}
# END W3TC Browser Cache

As you can tell, it’s a modified version of what the plugin creates, with a few lines removed, and a few more modified. The biggest problem I was having was with sitemaps, so I removed XML from the cache. Besides, the default setting is to not cache it, so you won’t notice a real difference.

Easiest way to deploy

I prefer to use snippets for configs like this that can change. All you need to do is create a file called cache in the /etc/nginx/snippets folder, and in your config add:

Include snippets/cache;

And that is where all the rules will be inserted.

Let me know any problems you have in the comments below, and I’ll do my best to help.

2 comments

    1. Yes, but if you’re using Apache as a backend, it will create the .htaccess version of the config, not the NGINX one

Leave a Reply(Markdown is On)