In web hosting one common challenge for server administrators is how to effectively manage the load on their servers, especially when running resource-intensive applications like WordPress. The solution? Implementing a caching HTTP reverse proxy, such as Varnish Cache, in front of your Nginx and PHP5.4 (PHP-FPM) web server.
Varnish Cache is a popular web accelerator that can work alongside either Apache or Nginx web servers. In this tutorial, we will focus on setting up Varnish to run on port 80, while Nginx operates on port 8080. This setup can significantly speed up your website’s delivery to visitors, reduce CPU time, and minimize database requests and file lookups.
By implementing Varnish Cache, you can enjoy several benefits. It can reduce server CPU load and time, increase website load speed, handle a large number of website visitors, and even support load balancing. For more information on the benefits and features of Varnish Cache, you can visit this page.
This tutorial will guide you through the process of setting up Varnish 3.0 in front of an Nginx, PHP5.4 (PHP-FPM) web server. The steps have been tested on CentOS 6, CentOS 7, Oracle Linux 7, and RHEL 7. If you are looking for other proxy server software options, you can check out this page.
Step 1: Setup Nginx, PHP5.4 (PHP-FPM) as Web Server
Before we can install and configure Varnish, we need to ensure that Nginx and PHP5.4 (PHP-FPM) are properly set up as your web server. If you need a guide on how to do this, you can refer to this tutorial.
Step 2: Install Varnish
The next step is to install Varnish on your server. This involves downloading the Varnish release package and installing it using the package manager.
[root@vps ~]# wget https://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm
[root@vps ~]# rpm -Uvh varnish-release-3.0-1.el6.noarch.rpm
[root@vps ~]# yum install varnish -y
Step 3: Configure Varnish
After installing Varnish, we need to configure it to work with our Nginx web server. This involves modifying the Varnish configuration files to specify that Nginx is running as the backend server on localhost at port 8080, while Varnish will run in front of it listening on port 80.
Modify /etc/sysconfig/varnish:
[root@vps ~]# vim /etc/sysconfig/varnish
Add the following. If your VPS running SSD disk, you can select varnish_storage as a cache method instead of memory (-s malloc):
.. .. DAEMON_OPTS="-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -u varnish -g varnish \ -S /etc/varnish/secret \ -p thread_pool_add_delay=2 \ -p thread_pools=2 \ -p thread_pool_min=400 \ -p thread_pool_max=4000 \ -p session_linger=50 \ -p sess_workspace=262144 \ -s file,/var/lib/varnish/varnish_storage.bin,512m" .. .. VARNISH_LISTEN_PORT=80 .. ..
Modify /etc/varnish/default.vcl:
[root@vps ~]# vim /etc/varnish/default.vcl
Add below:
backend default { .host = "127.0.0.1"; .port = "8080"; .connect_timeout = 600s; .first_byte_timeout = 600s; .between_bytes_timeout = 600s; .max_connections = 800; } acl purge { "127.0.0.1"; } sub vcl_recv { # Allow purge requests if (req.request == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } ban("req.url ~ ^" + req.url + " && req.http.host == " + req.http.host); return(lookup); } # Add header for sending client ip to backend set req.http.X-Forwarded-For = client.ip; # 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 ~ "^/[^?]+\.(gif|jpg|jpeg|swf|css|js|txt|flv|mp3|mp4|pdf|ico|png|gz|zip|lzma|bz2|tgz|tbz)(\?.*|)$") { unset req.http.cookie; set req.url = regsub(req.url, "\?.*$", ""); } # Don't cache admin if (req.url ~ "((wp-(login|admin|comments-post.php|cron.php))|login)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") { return (pass); } else { unset req.http.cookie; } } sub vcl_hit { # purge cached objects from memory if (req.request == "PURGE") { purge; error 200 "Purged"; } } sub vcl_miss { # purge cached objects varients from memory if (req.request == "PURGE") { purge; error 404 "Purged varients"; } } sub vcl_fetch { # Dont cache admin if (req.url ~ "(wp-(login|admin|comments-post.php|cron.php))|login" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") { return (deliver); } else { if ( beresp.ttl > 0s ) { unset beresp.http.set-cookie; } } } sub vcl_deliver { # Remove unnecessary headers remove resp.http.Server; remove resp.http.X-Powered-By; remove resp.http.X-Varnish; remove resp.http.Via; # DIAGNOSTIC HEADERS if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } }
Step 4: Configure NGINX to work with Varnish:
Configure default.conf:
[root@vps ~]# vim /etc/nginx/conf.d/default.conf
Add the following :
.. server { listen 127.0.0.1:8080; server_name localhost; ..
Configure common.conf:
[root@vps ~]# vim /etc/nginx/conf.d/common.conf
.. .. listen 127.0.0.1:8080; .. ..
Configure Vhost for domain example.com:
[root@vps ~]# vim /etc/nginx/sites-available/example.com.conf
Change listen to 127.0.0.1:8080; :
server { listen 127.0.0.1:8080; server_name example.com; rewrite ^/(.*)$ http://www.example.com/$1 permanent; } ..
Restart NGINX, php-fpm and Varnish:
[root@vps ~]# service nginx restart; service php-fpm restart; service varnish restart
Make sure NGINX listening to port 8080 and Varnish port 80:
[root@vps ~]# netstat -plunt | grep LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3119/varnishd tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 3065/nginx
Conclusion
This tutorial is just the beginning of your journey with Varnish Cache. There’s a lot more to explore and learn. For instance, you might want to look into other types of web servers, such as Apache, Litespeed, and more. You can find more information on these topics on this page.