How to configure & use Varnish Cache Server on CentOS 7

Estimated reading time: 6 min

Introduction

Varnish is an open source web accelerator software for websites and APIs. Varnish is very fast in serving requests as it caches the content into system memory and serves directly from there. As the disk is not involved in the process, it increases the performance by 300+ times. Varnish is meant to be installed as a reverse proxy in front of any web server running on HTTP. Varnish has its own configuration language to write policies on incoming requests such as back-end servers, ACLs, responses, etc.

In this tutorial, we will install Varnish 6.2 on CentOS 7. We will set up Apache as back-end server, listening on port 8080 and Varnish listening on default HTTP port 80. We will also set up Nginx listening on port 443 for SSL terminations. Varnish does not support SSL connections hence Nginx will work as an SSL reverse proxy for Varnish.

Prerequisites

  • Cloud VPS or Dedicated Server with at least 1GB RAM and CentOS 7 installed
  • You must be logged in via SSH as sudo or root user. This tutorial assumes that you are logged in as a sudo user.
  • A domain name pointed towards the server if you wish to enable SSL. In this tutorial, we will use example.com as an example domain name. Make sure to replace all occurrences of example.com with your actual domain name.

Step 1: Update the System

Update the system with the latest packages and security patches using these commands.

sudo yum -y update

Step 2: Set up Varnish YUM Repository

Varnish can be installed using many methods such as installing the RPM package from EPEL or compiling from source. In this tutorial, we will use package cloud repo for installing Varnish as it has the latest version of the application and it is maintained regularly by application authors. To make sure we install only authenticated package, install PyGPGME.

sudo yum -y install pygpgme yum-utils

Also, install the EPEL repository as some dependencies are only available there.

sudo yum -y install epel-release

Now, run the Package cloud repository setup script using the command.

curl -s https://packagecloud.io/install/repositories/varnishcache/varnish62/script.rpm.sh | sudo bash

Step 3: Install Varnish

Install Varnish by running.

sudo yum -y install varnish

After a successful installation, you can check the Varnish cache server version by running the command.

varnishd -V

You should see a similar output.

[client_18636_1@host ~]$ varnishd -V
varnishd (varnish-6.2.0 revision b14a3d38dbe918ad50d3838b11aa596f42179b54)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2019 Varnish Software AS

Varnish is now installed on your server. Let’s go ahead and put it to use.

To test our Varnish setup, lets Install Apache Web server on the same server. We will put Varnish as reverse proxy listening on port 80 and Apache listening on port 8080. Whenever a request for a web-page will come on Port 80, if the resource is available in the cache, Varnish will serve that directly from memory. If not, it will forward the request to the back-end server, in our case Apache on port 8080.

Step 4: Install Apache

Run the following command to install Apache web server.

sudo yum -y install httpd

Edit the Apache configuration file by running.

sudo vi /etc/httpd/conf/httpd.conf

Find the line number 42 saying Listen 80 and change the port number to 8080 as shown below.

#
#Listen 12.34.56.78:80
Listen 8080

#
# Dynamic Shared Object (DSO) Support

Restart Apache web server so that the changes can take effect.

sudo systemctl restart httpd

You can also enable Apache to automatically start at boot time by running.

sudo systemctl enable httpd

Configure the firewall to open port 80, 443 and 8080 by running these commands.

sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

Now, you can visit http:// 192.168.0.101:8080 to see the default Apache web page. Make sure to replace 192.168.0.101 with your server’s actual IP address.

Apache Default Page

Hurray!, Our Apache server is now running on port 8080. Let’s move forward and configure Varnish with Apache back-end.

Once you are done testing that Apache is working, let’s close the port 8080 as it is not recommended to expose unnecessary ports on the internet.

sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload

Step 5: Configure Varnish

By default, Varnish is configured to listen on port 6081. Let’s change it port 80 as port 80 is the default HTTP port. Edit the Varnish Systemd service file.

sudo vi /usr/lib/systemd/system/varnish.service

Find the following line at line number 24.

ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m

Change the port 6081 to 80 as shown below.

ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m

If you have spare memory in your server, you can also increase the maximum amount of memory allowed to Varnish for caching by increasing 256m. Save the file and exit from the editor.

Varnish configuration is done in VCL or Varnish Configuration Language. By default, Varnish puts a sample configuration file at /etc/varnish/default.vcl. It has back-end already configured as 8080 on localhost. If you wish, you may have a quick look at the configuration file by opening it in the editor.

sudo vi /etc/varnish/default.vcl

Have the look at the configuration shown below.

# Default backend definition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

The default back-end is listening on port 8080 on localhost. Exit from the editor without making any changes.

Once done, restart Varnish and enable it to automatically start at boot time.

sudo systemctl restart varnish
sudo systemctl enable varnish

Now if you go to http:// 192.168.0.101, you will see the same default HTTP web-page. To confirm that if it has been sent using Varnish, run the following command into the terminal.

curl -I  http://192.168.0.101/

You will see the following output.

[client_18636_1@host ~]$ curl -I  http://192.168.0.101/
HTTP/1.1 403 Forbidden
Date: Fri, 17 May 2019 10:12:52 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
ETag: "1321-5058a1e728280"
Accept-Ranges: bytes
Content-Length: 4897
Content-Type: text/html; charset=UTF-8
X-Varnish: 65557
Age: 0
Via: 1.1 varnish (Varnish/6.2)
Connection: keep-alive

Notice the X-Varnish and Via parameters. It tells us the web-page is indeed sent using Varnish. We received a 403 response code as we do not have any webpage at /var/www/html/directory.

Step 6: Install Nginx

Since Varnish does not support SSL, we need to use some other web server to listen for SSL connections. In this tutorial, we will use Nginx to handle SSL connections on port 443.

When a request will come to port 443, Nginx will forward it to Varnish running on port 80. If Varnish has the resource cached, it will reply to Nginx directly with the resource and Nginx will finally reply to the client on the same HTTPS connection. If the resource is not cached in Varnish, it will forward the request to backend Apache and reply to Nginx once Apache has responded with the resource.

Install Nginx by running.

sudo yum -y install nginx

Step 7: Generate Let’s Encrypt SSL Certificates

As we have already installed the EPEL repository, we can install Certbot directly using the command.

sudo yum -y install certbot

Certbot is a very popular client to generate Let’s Encrypt certificates. By default, Apache is configured to serve the website located at the directory /var/www/html. We will use this location as our webroot directory to generate the certificates. If you have your website installed in any other location, replace /var/www/html with the actual path of your website’s webroot.

Note: The domain which you are using must be pointed towards your Snel server. Let’s Encrypt will verify it before issuing the certificates.

Now, run the following command to generate Let’s Encrypt certificate.

sudo certbot certonly --webroot -w /var/www/html -d example.com

The command will ask you for your email address for renewal notices. It will also prompt for accepting terms and conditions. Once certificates have been obtained, the private key will be stored at /etc/letsencrypt/live/example.com/privkey.pem and the full certificate chain will be stored at /etc/letsencrypt/live/example.com/fullchain.pem.

As Let’s Encrypt certificates are expired in 90 days, we need to configure automatic renewals also. For automatic renewals, open crontab for root by running the command.

sudo crontab -e

Put the following line into the editor.

0 4 * * * /usr/bin/certbot renew --post-hook "systemctl restart nginx"

The above command will attempt to automatically renew your certificates every day at 4 AM. If your certificates are not due for renewals, it will not do anything. If certificates are renewed, it will automatically restart the Nginx web server so that new certificates are loaded.

Step 8: Configure Nginx

Now that we have generated the certificates, let’s configure Nginx.

Open the default Nginx configuration file by running the command.

sudo vi /etc/nginx/nginx.conf

In line number 38 to 57, you will find a server block that is configured to listen to port 80. We do not need Nginx to listen on port 80 as we already have Varnish configured to listen on port 80. Replace the whole server block with the following configuration.

server {
        listen 443 ssl;

        server_name example.com;
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        location / {
            proxy_pass http://127.0.0.1:80;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Port 443;
            proxy_set_header Host $host;
        }
}

Save the file and exit from the editor. Restart all Web Server related services so that our changes can take effect.

sudo systemctl restart varnish
sudo systemctl restart httpd
sudo systemctl restart nginx

You can test if SSL is working on your site by browsing to https://example.com/ from any web browser. If you would like to confirm if the webpage is indeed sent via Varnish, run this command on a terminal.

curl -I https://example.com/

You should see a similar output. Notice the X-Varnish and Via parameters. It tells us the web-page is indeed sent using Varnish.

[client_18636_1@host ~]$ curl -I https://example.com/
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Mon, 20 May 2019 06:24:07 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 4897
Connection: keep-alive
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
ETag: "1321-5058a1e728280"
Accept-Ranges: bytes
X-Varnish: 65555
Age: 0
Via: 1.1 varnish (Varnish/6.2)

Conclusion

In this tutorial, we have learned how to install Varnish cache server on CentOS 7. We have also installed Apache as the back-end to Varnish server. We configured Varnish to listen on port 80 as the default web server. We also activated SSL on our website using Let’s Encrypt and Nginx reverse proxy listening on port 443.

Was this article helpful?
Dislike 0
Views: 13962

Reader Interactions

Comments

  1. Mojtaba says

    Why use not used apache webserver for SSL configurations? Is it required to have both apache and nginx webservers installed for enabling SSL?

  2. Michael Kormendy says

    "Since Varnish does not support SSL, we need to use some other web server to listen for SSL connections. In this tutorial, we will use Nginx to handle SSL connections on port 443.

    When a request will come to port 443, Nginx will forward it to Varnish running on port 80. If Varnish has the resource cached, it will reply to Nginx directly with the resource and Nginx will finally reply to the client on the same HTTPS connection. If the resource is not cached in Varnish, it will forward the request to backend Apache and reply to Nginx once Apache has responded with the resource."

  3. irawan says

    the best Tutorial!!! i've tried thousands of tutorial for configuring varnish+apache, earlier i try to use hitch for SSL termination but didn't work well, nginx is the best solution this is the best! and easiest!
    Many THANKS

Leave a Reply

Your email address will not be published. Required fields are marked *