Using Nginx FastCGI Cache With WordPress
Are you sick of using different caching plugins? Are you sick of updating plugins and checking to make sure there are no updates to Nginx rules? Are you happy to get your hands a little dirty and write your own Nginx rules? Then this might just be the tutorial for you. Let’s take a look at how you can get your WordPress based website using Nginx FastCGI cache.
It should be noted that you still need a plugin, but this one is not to run the caching. This plugin is simply to allow you to conveniently clear the cache (and clear it after making posts etc) from the WordPress admin. I also expect that you have a somewhat decent knowledge of editing Virtual Host files used by Nignx, if you don’t I would suggest familiarising yourself with how to make Virtual Hosts first.
Install Nginx Extras
You most likely have Nginx installed already, but chances are high that it is from the default repo and that you don’t have the modules required to use the Nginx FastCGI cache. To solve this with the least disruption we can add the needed repo and grab Nginx Extras from it.
1 2 3 4 |
sudo apt-get update sudo add-apt-repository ppa:nginx/development sudo apt-get update sudo apt-get install nginx-extras |
You’ll likely get a message asking you to resolve a conflict with your existing nginx.conf
file. If you know you haven’t modified the nginx.conf
file you can probably overwrite with the file from the repo. If you have made changes you will need to resolve the conflict. This most important thing is to make sure the following is in your nginx.conf
file.
1 |
include /etc/nginx/modules-enabled/*.conf; |
Once that is done you are ready to adjust your Virtual Host file. Some of this is completely depends on your website, but for the most part it should be fairly similar. I have removed anything to do with my SSL certificate, you should add you own back in or if you use Certbot just leave the parts it added for you intact.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; add_header X-FastCGI-Cache $upstream_cache_status; server { root /path/to/html/return-true.com; # Add index.php to the list if you are using PHP index index.html index.htm index.nginx-debian.html index.php; server_name return-true.com www.return-true.com; set $skip_cache 0; if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { set $skip_cache 1; } if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. #try_files $uri $uri/ =404; try_files $uri $uri/ /index.php$is_args$args; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { include snippets/fastcgi-php.conf; # With php7.0-cgi alone: # fastcgi_pass 127.0.0.1:9000; # With php7.0-fpm: fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_cache WORDPRESS; fastcgi_cache_valid 200 301 302 404 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one location ~ /\.ht { deny all; } location ~ /purge(/.*) { fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1"; } # SSL Include Here } |
I’ve changed paths etc to not reveal too much information. I encourage you to change things too. You can change the cache name and path to something more sensible. Don’t forget to change your the domain and path to your own if you decide to just copy/paste. You also want to make sure that the total memory used does not exhaust your available RAM. The amount of memory is defined in the first line after WORDPRESS
.
Once you have added this you can test your configuration using:
1 |
sudo nginx -t |
If you get a message saying there were no errors, you are good to go. Restart or reload Nginx and you should be able to check if your page is being cached by using a incognito tab and checking the network tab of Chrome Dev tools (or FireFox Dev tools) for the X-FastCGI-Cache
header. If it says ‘HIT’ after an initial page load to prime the cache then you are up and running.
Clearing The Cache
The best way too make it easy to clear the cache in WordPress is to install a small plugin. This will enable you to clear it manually or it will do so automatically after making a new post, commenting, etc. This plugin is called ‘Nginx Cache’ by Till Krüss and can be installed from your WordPress admin. Once installed head to the options page under the Tools menu and input the path you used for your cache.
Troubleshooting
It is by no means simple to get this cache up and running if you don’t deal with Nginx too often so it is fairly easy to hit problems. I didn’t come across anything in particular I can give you a heads up about, just to double check your spelling of things in your Nginx Virtual Hosts files, although the Nginx configuration test is great at letting you know if you got something wrong.
Another note is to always be careful. It is very easy to break your website completely, it might be a good idea to have a copy of your initial config so you can put it back in the case of any major issues.
As always if you have any problems please do let me know via the comments and I will try to help as best I can.
1 Comment
Kyriakos
I enabled your setup at a huge WooCommerce store. Before that, it was using Varnish with Apache, and it was too slow! Esp, the product listing and the checkout process.
Thanks a lot!