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 ofexample.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.
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.
David Ström says
for SELinux you have to run
setsebool -P httpd_can_network_connect 1
for nginx to forward to varnish
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?
Ahmet Bas says
No, it's not required to have nginx as apache. But in this article both are used.
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."
isix says
The question was: "Why use not used apache webserver for SSL configurations? "…
Ahmet Bas says
In this setup/article Apache is only used to serve content and Nginx is used for SSL termination
Manveer says
Hi,
Can you please guide me, How to configure varnish with apache on port 443 and 80.
I don't want to use Nginx for 443 port.
Ahmet Bas says
May I ask you why you do not want to use Nginx ?
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