• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Varnish for WordPress in a Docker container in Plesk Onyx

E

Enric Oon

Guest
Is your website experiencing heavy traffic? Are you looking for a solution that will reduce server load and will improve website speed? Varnish might just be what you need. Varnish listens for duplicate requests and provides a cached version of your website pages, mediating between your users’ requests and your server.

So how do you activate Varnish in Plesk Onyx? In this article, I will show you how you can easily increase your website speed by using Varnish as a one click Docker container running on Plesk. I will demonstrate how using a website caching solution like Varnish can easily improve both page response times and the maximum number of concurrent visitors on your website. To simulate real traffic and measure correct response times, I have used an external server similar to blitz.io, stormforger.com or loadstorm.com to generate lots of traffic and concurrent users to our site.

What is Varnish and why should you use it?




varnish-logo-1024x350.png


Varnish is a software that helps reduce the load on your server by caching the output of the request into the virtual memory. It is a so-called HTTP accelerator and is focused on HTTP only. Varnish is open source and is used by high traffic websites such as Wikipedia.

If you have lots of daily visitors, we recommend using a cache mechanism. You’ll see your response time improving significantly because the server can send the already cached data, directly from the memory, back to the client, without the resource consuming process handling on the web server. Additionally, it reduces the load on the CPU so that the server is able to handle many more requests without getting overloaded. I will demonstrate this in the stress tests later.

Running Varnish as a Docker container


Docker is a great open source project that makes it incredibly simple to add Varnish to a running server. We don’t need to install Varnish on the production server, we simply use a ready-to-go Varnish Docker image. The main advantage is that if something goes wrong with the container, we can simply remove it and spin-up a new container within seconds. The way in which Docker containers are designed guarantees that Varnish will always run independently of our system environment. Do you want to know more about Docker containers? Read more about the 6 essentials on Docker containers!

I will use the newly integrated Docker support in Plesk Onyx to activate Varnish. The Plesk interface makes it easy to get a Varnish instance running. We will still use terminal but only for small modifications of the Varnish configuration file. A further improvement would be to rebuild the Varnish Docker image so that it takes our configuration as parameter from the Plesk UI. For now, I’ll stick to the original Docker image and upload our configuration via shell.

Activate Varnish in Plesk Onyx and test on a static page


Okay, let’s try it first on the default static page of Plesk Onyx. In the default settings, Plesk uses Nginx as a reverse proxy server for Apache. This means that Nginx is listening to default port 80(443 for HTTPS) and Apache to an internal port (7080 HTTP, 7081 HTTPS). We will push our Varnish container in between of the two web servers. In this scenario, Varnish will get the request from Nginx and the content from Apache. Don’t worry, it’s easier than it sounds!

Go to Docker and search for the image “million12/varnish” in the Docker Image Catalog. Once found, click “run” and Plesk will download the image to your local machine. After the download, click “run (local)”, which will open the configuration page of the container. The only thing that we’ll change is the port mapping.

varnish-docker-plesk-port-mapping-1-1024x521.png

Varnish in Docker container on Plesk Onyx – Port mapping


Remove the tick at the option “Automatic port mapping” and set an external port (I will use port 32780 in this tutorial) for the option “Manual mapping”. This means that port 80 of the container is mapped to the external port 32780. By adding a proxy rule we can “talk” to the container through this external port. We will set the backend server in Varnish to the Apache port from where the data will be gathered if a “cache miss” occurred.

Test the Varnish functionality with a static page


Create a subdomain for testing our Varnish integration on a static page. After the subdomain was created, go to the “Hosting Settings” and deactivate the options “SSL/TLS support” and “Permanent SEO-safe 301 redirect from HTTP to HTTPS” because we want to test the Varnish functionality over HTTP first. Okay, but how do we redirect the requests to the Varnish container? This can be done easily with the option Docker Proxy Rules that you will find in the domain overview.

varnish-proxy-rules-plesk-onyx-2-1024x350.png

Varnish – Proxy rules for Docker container on Plesk Onyx


Click on “Add Rule” and select the previously created container and the port mapping that we entered manually. If you cannot make a selection, then your container is not running. In this case you should click on Docker in the menu and start the container first. If you open the subdomain after you’ve activated the proxy rule, you will see the error Error 503 Backend fetch failed. Don’t panic, this is an expected behavior. We did not configure the Varnish backend server yet!

varnish-error-503-backend-fetch-failed.png

Varnish – Error 503 Backend fetch failed

Configure Varnish properly in the Docker container using SSH


This is the only time when we need to access the server and the Varnish Docker container via SSH. Open your terminal and type

$ ssh [email protected] // Replace with your user name and correct IP address

Enter your password if required to get access to the server. Tip: use a private / public key pair to improve the security of your server!

First of all, we need to find out the ID of our Docker container. To list all active container type into the command line

$ docker ps
varnish-running-docker-containers-plesk-onyx-3-1024x55.png

Varnish – Running Docker containers – Plesk Onyx


Copy the Docker ID and use the following command to access the Docker container

$ docker exec -it ID bash // Replace ID with the correct container ID

Okay, the most important thing to do is change the host and port value for the default backend server in the file /etc/varnish/default.vcl.

For .host we will enter the IP address of the server where Plesk is executed (in our example 111.222.333.444) and for .port 7080. As mentioned before, this is the default Apache HTTP port in Plesk. We have to use this port because, internally ,Varnish can only speak over an unencrypted channel!

Tip: Do we have a cache hit or miss?


How do we see that the content was loaded from the memory and not from the Apache server? You will see that the request was processed by Varnish through a special header entry in the response, you will not know whether the data was loaded from the memory or was requested from the Apache server.

To achieve it without having to use varnishlog in the console, we can set another header value with the corresponding value (cache hit / cache miss). We have to use the function sub vcl_deliver that is the last exit point for almost all code paths (except vcl_pipe). Add the following code within the curly brackets of the function sub vcl_deliver

if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
Use the Developer Tools in your browser to examine the response


Save the modified file and exit the container. Switch to your Plesk UI again and restart the container in Docker with the “Restart” button. When you see the success message, go to the tab of the subdomain with the 503 error message. Do not reload the page yet but open the Developer Tools first (alt + cmd + i on a MacBook). Go to the “Network” tab and reload the page. Select the first entry (URL /) and take a closer look at the “Response headers”.

varnish-cache-miss-4-1024x334.png

Varnish – Cache Miss


If everything was done properly, you will see some new header variables:

X-Cache – This is the variable that I’ve defined in the configuration file. After the first reload it should display a “MISS”.
X-Varnish: ID – The internal ID for this file in Varnish {more information required}
Via: "1.1 varnish-v4" – This shows that the request was redirected through the Varnish container.

Okay, it’s about time to see some Varnish magic! Click on the reload button in your browser to reload the page. This time it will be loaded from the virtual memory.

varnish-cache-hit-5-1024x295.png

Varnish – Cache Hit

What about websites that are using HTTPS to encrypt the connection?


It also works and the best part of it is that you don’t have to change anything! Create an SSL certificate for the subdomain using the great Let’s encrypt extension. After the certificate was created and assigned (the extension does it automatically), go the the static page and reload it using https:// instead of http://. If you open your browser console, you will see a X-Cache: HIT in the response headers:

Activate Varnish caching in your WordPress website


We just saw that it’s technically possible to activate Varnish inside a Docker container with Plesk. Now let’s try it on a WordPress website!

The main difference is the configuration of the VLC configuration file within the Varnish container. WordPress is a dynamic CMS, thus we cannot cache everything without restricting the functionality of the system; the administration pages shouldn’t be cached since changes wouldn’t be possible any more for logged in users.

There are many pre-defined configuration files for WordPress available on the internet, from various developers. In most cases, you can use them right away without any modifications. For our test integration, we will take the configuration file created by HTPC Guides (with small adjustments – link below).

For this article and for the stress tests I’ve created a fully workable website with WordPress. I want to test under real conditions and not with a default WordPress installation. The website should also be secured with an SSL certificate and only callable over HTTPS. For this reason, I will also activate an SSL certificate with the help of the Let’s Encrypt extension for this installation.

Use a WordPress Plugin to activate support for HTTPS


Important: Do not use the option “Permanent SEO-safe 301 redirect from HTTP to HTTPS” within Plesk in “Hosting Settings” because this will lead to a redirect loop in our special environment constellation. Instead I will use a WordPress plugin to switch our installation completely to HTTPS. The name of the plugin is Really Simple SSL and can be downloaded from the official plugin repository.

Please make the same preparations like for the static page but add this time the additional required configuration data for WordPress to the default.vcl configuration file inside the Docker container. I’ve used the this Varnish configuration file (GitHub Gist) for my test installation. Don’t forget to adjust the backend server again like we already did for the static page!

Tip: Do not forget to restart the Docker container from the Plesk UI to reload the configuration information. If you forget to restart the container, then Varnish will not work properly with the WordPress website.

Now reload the front page of WordPress with the browser console open. The first loading process should throw an X-Cache: MISS but the second (and following) reloads will return an X-Cache: HIT.

varnish-wordpress-cache-hit-6-1024x204.png

Varnish in WordPress – Cache Hit

Let’s make some stress tests with Blitz.io!


We’ve seen that Varnish helps to improve the performance of the website. What is with the promised load reduction on the CPU? I can test it with the so-called stress testing which will load the website with many concurrent users per second for a certain time span. Without any security and overload protection, the server will start to respond steadily slower until the requests cannot be handled any more completely. With activated Varnish the server will be able to serve such intensive requests longer without throwing errors.

All right, it’s time to run load and performance tests with the external service provider Blitz.io.

Note: I used a very small server for this test instance (only 1 CPU and 500MB Memory), so the positive impact of Varnish should be much higher on a more powerful server!

Result WITHOUT Varnish:

wordpress-without-varnish-1024x395.png

Stress test – WordPress without Varnish


As you can see, I had to abort the stress test because the server already couldn’t handle the request after less than 5 seconds and less than 50 concurrent users. After just 15 seconds the server collapsed completely and no requests could be managed any more!

Result WITH Varnish:

wordpress-with-varnish-1024x483.png

Stress test – WordPress with Varnish


Varnish magic! As you can see, the Varnish cache allows to keep the server stable even under heavy load. The small test server handled over 300 concurrent users and responded all requests over 30 seconds without any errors. After 30 seconds and over 300 concurrent users the server was overloaded and couldn’t accept further requests. With a more powerful server the numbers should be much higher! So, it’s also great to keep your website reactively if it suffers a DDoS attack, at least for a certain number of requests.

Summary: Varnish for WordPress within a Docker container in Plesk


Let me make a small checklist:

  • Varnish in Docker container? Yes.
  • Varnish in WordPress? Yes.
  • Varnish in Plesk? Yes.
  • Varnish for WordPress within Docker container in Plesk? Hell, yes!

Mission accomplished!
1f642.png


As you’ve seen, Varnish can greatly improve the performance of your WordPress website and reduce the CPU-load of your server. It’s relatively easy to setup a working environment using Varnish in a Docker container between Nginx and Apache within Plesk. The most important part is the correct configuration of Varnish for your specific CMS.

Thank you for reading. In the next blog post I will take a look on another memory caching system (Memcached).

Stay tuned and Plesk!

The post Varnish for WordPress in a Docker container in Plesk Onyx appeared first on Plesk.

Continue reading...
 
Wonderful piece really, but I would love to see some feedback in regard to purging / banning cache with this.
Reason is because I have tried a lot but cant find a way to do this correctly.
 
Patrick,

If you're using WordPress, install W3 Total Cache. You can insert information for cache purging in there (IP address). This will do it when posts are edited etc. Here's some example VCL:
Purging and banning — Varnish version 4.0.5 documentation

Also, the W3 Total Cache plugin has vcl files inside its plugin directory. It's located here: /wp-content/plugins/w3-total-cache/ini/varnish-sample-config.vcl

And looks like:
backend default {​
.host = "127.0.0.1";
.port = "8080";
}

acl purge {
# Web server with plugin which will issue PURGE requests
"localhost";
}

sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("req.url ~ ^" + req.url + "$ && req.http.host == " + req.http.host);
}

# Normalize content-encoding
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}

# Remove cookies and query string for real static files
if (req.url ~ "\.(bz2|css|flv|gif|gz|ico|jpeg|jpg|js|lzma|mp3|mp4|pdf|png|swf|tbz|tgz|txt|zip)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}

if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" ||
req.url ~ "preview=true" ||
req.url ~ "xmlrpc.php") {
return (pass);
}

return (lookup);
}

sub vcl_fetch {
# Don't cache backend
if (req.url ~ "wp-(login|admin|comments-post.php|cron.php)" ||
req.url ~ "preview=true" ||
req.url ~ "xmlrpc.php") {
# Dont modify anything, it's (pass) object
} else {
unset beresp.http.set-cookie;

if (beresp.status == 307) {
# Don't cache temporary redirects like ?repeat=w3tc
set beresp.ttl = 0h;
} else if (req.url ~ "\.(bz2|css|flv|gif|gz|ico|jpeg|jpg|js|lzma|mp3|mp4|pdf|png|swf|tbz|tgz|txt|zip)$") {
set beresp.ttl = 30d;
} else {
set beresp.ttl = 4h;
}
}
}

sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}

sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}​
 
Hi Alawson, thanks for your reply.
I eventually got it working with a specific plugin but had to change the default logic from purge to ban for some unclear reason.
Stil thans for taking the time to give me a reply, very much appreciated!!
 
hello

i am unable to purge cache on post update , please tell me how can i make wordpress purge. Can W3 Total Purge ??
 
Hi Alawson, thanks for your reply.
I eventually got it working with a specific plugin but had to change the default logic from purge to ban for some unclear reason.
Stil thans for taking the time to give me a reply, very much appreciated!!
Hello Patrick !!
I am unable to purge cache on post update , please tell me how can i make WordPress purge. Can W3 Total Purge ?? Please tell me whcih plugin are you using to purge vrnish in docker. Everything is working fine and i made few changes in vcl file to stop caching feeds and api data but not able to purge articles white editing. I am using Wp Rocket plugin.
 
Hi,
i'm follow this tutorial in order to enable varnish cache server on my plesk onyx.
I've edit /etc/varnish/default.vcl putting on 'host' the plesk address (private ip this is behind NAT) and on port 7080.

but i've always same error 503 error.

where i'm wrong?
 
Hi,
i'm follow this tutorial in order to enable varnish cache server on my plesk onyx.
I've edit /etc/varnish/default.vcl putting on 'host' the plesk address (private ip this is behind NAT) and on port 7080.

but i've always same error 503 error.

where i'm wrong?
hello

its easy to configure varnish through docker but it will not purge the homepage and posts and api and feed if you are using wordpress. i have setup it on PagalParrot - Latest News,Viral Stories, India News, Breaking News, Business, Bollywood, Cricket, Videos & Photos and you can check its working fine .
you can contact me via contact form if you need help
 
Hello,

thanks for sharing this tuto. i've done all step by step, i was stuck in wordpress as i've had always redirect loop. i've used another ssl plugin and finally got it work.

but i have a problem, the main page still has a loop and i can't solve nor understand how it can happen, all other pages works perfectly.

thanks alot
 
Hello,

thank you for this ncie tutorial.
For me everything is working as long I do not use the 301 redirect to https.

My response is not just limited to Wordpress, even when I host a static page its not working with the 301 redirect to https.
Is there a 'real' solution for this or not?
Maybe @IgorG can help here?

I would like to use Plesk Onyx 17.5.3 this way if possible:
Nginx --> Varnish (Docker) --> Apache

Or like this:
Varnish (Docker) --> Apache

Here some specs:

System: Debian 8.10
Plesk: Plesk Onyx 17.5.3 Update Nr. 37

I would like to use Varnish as Caching Tool for:

- Wordpress
- Typo3 v8
- Drupal v7 & v8



Best regards from Germany
 
Hello,

I have followed the instructions exactly, but I get the error:

Error 503 Backend fetch failed

Backend fetch failed
Guru Meditation:

XID: 4947971

Varnish cache server
 
Not going to lie, I've spent weeks worth of hours trying to implement this with no success. I get the same thing as "Error 503 Backend fetch failed" regardless of configuration recommendations, etc.
 
Last edited:
Same problem. I follow step by step but get the same thing as "Error 503 Backend fetch failed".

Plesk 17.8.11
Ubuntu 16.04.5 LTS‬

Has anyone found a solution?

Also experiencing this on:

Plesk Version 17.8.11
CentOS Linux release 7.5.1804
 
"Error 503 Backend fetch failed". Theres no garuntee this issue is the same for all users, but it does relate to the data not being "available" varnish.
Check your ports, your rules etc restart varnish if you change the vcl file and see what happens. Getting Varnish running is quite basic, but getting it operating as needed can be a little more complex.

For purging you need to configure varnish to do so, this is from an old Varnish 3 install,

Create a list of allowed locations that can purge (any servers)
acl purge {
"localhost";
"127.0.0.1";
"x.x.x.x";
"y.y.y.y"
}


then add a rule in sub vcl_recv

sub vcl_recv{
# is the request a PURGE type
if(req.request == "PURGE")
# is the client in the purge list i.e. the web server requests the event
if(!client.ip ~ purge){
# error because it is not configured.
error 405 "Not allowed";
}
# skip the rest of the routine, Lookup.
return (lookup);
}


Please Note there are a number of resources available for configuring varnish, however you must have a decent understanding of how things work, i..e. Removing cookies can break logins etc, if your simply working with WordPress there are some template examples around for getting that setup, make sure to backup before you make any changes as always.
 
Tried a couple of "Wordpress-based" templates as well with no luck. I'm also making sure to restart the varnish container after each vcl change. I've tried several containers and get the same thing, so it must be something on my side.
 
Back
Top