Important Note
Based on the Step-by-step: Speed Up WordPress with Varnish Software article originally written by Federico G. Schwindt and published on Web Designer Magazine - http://www.webdesignermag.co.uk/ as well as on the Varnish Software blog.
It is now available in the Varnish Web Developer Wiki, specifically under the Varnish with WordPress Tutorials section. As with any other wiki docs you can help us to expand it and keep it up to date. I'm publishing it here in the blog for reference. Read on:
The aforementioned article was written for OSes using sysvinit and BSD init. Now that systemd is in most Linux distributions, we have written this tutorial’s examples to account for that. Still, it should be generic enough to work for most systems.
One of the most common things we hear is a need to speed up WordPress and improve the performance of WordPress overall - we are often asked how Varnish can be used to give WordPress the boost its users need. With that in mind, the article linked above was published to help with this common challenge, and has since been one of the most popular blog articles we've ever published.
In this tutorial, we give the step-by-step process an update, going through some of the common steps required to install and configure Varnish and integrate it with WordPress to take your site to the next level. Let’s get started.
This article assumes that you have a running instance of WordPress and that you have administrator rights for said instance, both at the OS and application level. We have tested this using Ubuntu LTS 16.04, Varnish Cache 4.1 and WordPress 4.4.
1. Installing Varnish
In case you have not done so yet, you will need to follow the instructional section on how to Install Varnish before we can continue.
2. Add the plugin
After installing Varnish we need to instruct WordPress to purge the cached content whenever it is modified. There are several plugins to achieve this.
In this tutorial we will use Varnish HTTP Purge Plugin. Go to the WordPress dashboard, click on Plugins Add New and search for the Varnish HTTP purge plugin. Click on ‘Install Now’ and confirm. Finally, activate it.
3. Enable custom permalinks
For the Varnish HTTP purge plugin to work correctly we need to enable mod_rewrite and use a custom URL structure for permalinks and archives. In the WordPress dashboard click on Settings Permalinks and select ‘Custom Structure’.
Then type /%year%/%monthnum%/%post_id% and click on ‘Save Changes’. To finalize, open a command prompt and run the following as root.
a2enmod rewrite
4. Move Apache’s port
Before we configure Varnish to handle all the web traffic that comes to our WordPress site, we will need to move Apache to a different port. Let’s then change all occurrences of port 80 to 8080 using a text editor as show below.
/etc/apache2/ports.conf
and any files under
/etc/apache2/sites-enabled/
These changes make sure that Apache now uses port 8080 to serve your WordPress site as we will need Varnish to take over the HTTP content serving to all web clients, which normally is done from port 80.
5. Serve from Varnish
In order to get content served from Varnish you will need to make a few changes that are documented thoroughly in the Varnish Tutorial in this wiki. Please make sure you have that covered.
6. Set the backend
Varnish uses the concept of backend or origin server to define where it should retrieve the content from if it’s not persistent in its cache. In this case we will be using the Apache location that we defined in Step 4 as the backend. Edit /etc/varnish/default.vcl with a text editor and ensure the following is present.
backend default {
.host = “127.0.0.1”;
.port = “80”;
}
7. Make it effective
Now that all the preparations are complete we are ready to start Varnish and restart Apache. Once this is done, all traffic to our WordPress site will pass through Varnish before it hits the Apache server. Open the command prompt again and run the following as root.
sudo systemctl restart varnish.service
sudo systemctl restart apache2.service
8. Ignore cookies
Ignore cookies by default. Varnish will not cache content for requests including the cookie or header or responses including the Set-Cookie header. WordPress sets many cookies that are safe to ignore during normal browsing so let’s update /etc/varnish/default.vcl and add the following inside vcl_recv to remove them.
#unsetting wordpress cookies
sub vcl_rec{
..
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-\d+=[^;]+(; )?", "");
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-time-\d+=[^;]+(; )?", "");
set req.http.cookie = regsuball(req.http.cookie, "wordpress_test_cookie=[^;]+(; )?", "");
if (req.http.cookie == "") {
unset req.http.cookie;
}
}
9. Exclude URLs
In most web applications there are some URLs that shouldn’t be cached no matter what, and WordPress is no exception. We will be excluding any admin or login related pages from hitting the cache. Once again open /etc/varnish/default.vcl and add the following before we remove the cookies from the previous step.
# exclude wordpress url
if (req.url ~ "wp-admin|wp-login") {
return (pass);
}
10. Extend caching
Varnish uses the max-age parameter in the Cache-Control HTTP header to establish how long the content is considered fresh before contacting the backend again. Varnish will use 120 seconds by default if this value is missing or is equal to zero. To extend this period to one hour we could update /etc/varnish/default.vcl.
# extending caching time
sub vcl_backend_response {
if (beresp.ttl == 120s) {
set beresp.ttl = 1h;
}
}
11. Handling purge requests
Whenever existing content in WordPress is updated, Varnish HTTP purge will ask Varnish to remove it from the cache. The next time it’s requested, the most up-to-date version will be retrieved from the backend. But in order to do this we will need to add the following codes at the top of vcl_recv in /etc/varnish/default.vcl.
The first bit of code is to specify which IP addresses can access the config files.
acl internal {
"192.x.x.x"/24;
xxx.xxx.xx.xx;
}
# Allowing which address can access cron.php or install.php,
# add the following in acl.
This next one is for when purge requests are handled and how to handle them:
#handling purge requsets
sub vcl_recv{
...
if (req.method == "PURGE") {
if (req.http.X-Purge-Method == "regex") {
ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
return (synth(200, "Banned."));
} else {
return (purge);
}
}
}
12. Secure purge
In the previous step we added the necessary code to handle purge requests but we have left it open for anyone to do just that. Let’s add some code to restrict it. Edit /etc/varnish/default.vcl and after the backend add the acl below using your server IP address or hostname. Then modify the code in the previous step to use it.
acl purge {
"localhost";
server ip address or hostname;
}
...
if (req.method == "PURGE") {
if (client.ip !~ purge) {
return (synth(405));
}
13. Reload the configuration
Before our changes to etc/varnish/default.vcl take effect, Varnish needs to be told to reread its configuration. To avoid any potential downtime, Varnish can be instructed to reload the configuration while it keeps serving requests. Open the command prompt again and type the following as root.
#reload varnish
systemctl reload varnish.service
14. Empty the cache
Chances are that as we worked our way through the configuration, some content found its way into the cache even if it wasn’t supposed to. In this situation we can use the Varnish HTTP purge plugin to empty the cache and then we can start afresh. Go to the WordPress dashboard and click on Purge Varnish at the very top.
15. Examine the traffic
Everything is working; browse some pages, login, logout, pages are loading fast. Or are they? Varnish comes with a set of tools that will help you understand what’s going on behind the scenes and debug any potential problems. To see the requests as they are passing through Varnish, run the following on a command prompt: varnishlog
16. Volume matcher/measure
Varnish is very powerful but can be daunting at first. Luckily for us there are many resources online and Varnish has an active community behind it ready to help. If you are stuck or want to know more you can visit the varnish cache website or search in this wiki for a solution.
17. Go further
If you are interested in Varnish, you can always give Varnish Plus a go. There’s a free trial available. You can capture real-time traffic statistics, create a paywall for premium content, simultaneously work on administration across all Varnish servers, record relationships between web pages for easy content maintenance, detect devices used for browsing, accelerate APIs and more.
Check out the links on our main WordPress page to take your WordPress-Varnish site even further.
Photo (c) 2009 Baltimore City Paper used under Creative Commons license.