Drupal with Varnish caching and HTTPS using Nginx and Let's Encrypt

Varnish is great at serving pages to anonymous users at high speed, but it doesn't speak HTTPS so if you want to use Varnish and provide your site over HTTPS then you need to use something to do HTTPS and proxy the traffic to Varnish. In this blog post I will detail one way to do this by using Nginx to do HTTPS termination and proxy the requests to Varnish.

Server overview

In the following setup Varnish listens for HTTP requests on port 80. Apache with mod_php handles the Drupal stuff, listening on port 8080. Varnish proxy requests from port 80 to Apache on port 8080. To handle HTTPS, Nginx listens on port 443 and proxies requests to Varnish on port 80. Let's Encrypt provides a free SSL certificate for use by Nginx.

The following commands work on Ubuntu 18.04. The configuration will generally work for different versions of Ubuntu or Debian, although the versions of some software packages will vary; PHP and Varnish in particular have changed from previous long term support versions of Ubuntu.

Apache setup

We start by installing Apache and PHP and configuring Apache to listen on port 8080.

sudo apt-get install -y apache2 apache2-utils php7.2 php7.2-cli php7.2-common php7.2-curl php7.2-json php7.2-gd php7.2-mysql php7.2-opcache php7.2-xml libapache2-mod-php7.2
sudo a2enmod expires headers rewrite php7.2

Create an Apache virtual host file in /etc/apache2/sites-available/example.conf

<VirtualHost *:8080>

    ServerName example.com
    ServerAdmin support@example.com
    DocumentRoot /var/www/html

    ErrorLog /var/log/apache2/example-error.log
    CustomLog /var/log/apache2/example-access.log combined

    <Directory /var/www/html>
        Allow from all
        Options +Includes -Indexes +FollowSymLinks
        AllowOverride all
    </Directory>

</VirtualHost>

Edit the /etc/apache2/ports.conf so that it contains

Listen 8080

Then reconfigure Apache

sudo a2ensite example.conf
sudo systemctl restart apache

Assuming Drupal is installed in /var/www/html, then it will be available at http://example.com:8080/

Varnish setup

If the varnish software package isn't found then you will need to enable the Ubuntu universe repository

sudo add-apt-repository universe

Create a file called /etc/systemd/system/varnish.service with the following content; the arguments for varnishd can be tweaked according to your requirements.

[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/5.2/ man:varnishd

[Service]
Type=simple
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T :6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m -p vcc_allow_inline_c=on
ExecReload=/usr/share/varnish/reload-vcl
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true

[Install]
WantedBy=multi-user.target

Edit the /etc/varnish/default.vcl file for your specific requirements. The key thing is to add a backend that points to port 8080, like:

# Default backend definition. Points to Apache on port 8080.
backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .first_byte_timeout     = 300s;
  .connect_timeout        = 5s;
  .between_bytes_timeout  = 2s;
}

 

Back to blog