Skip to content Skip to footer

How to set up multi-site Magento 2.X Varnish backend with Apache and SSL

The following guide that you have one Magento website running (i.e. “mydomain.com”, listening on port 8080), Apache and Varnish (port 80) are on the same host.

Once you have a second site (i.e. “mydomain2.com”) pointing your server IP, SSL installed for this server, Magento ready, the Apache and Varnish setup should look like below.

The trick here is to have the second site listen on a different port in Apache (here port 8081) and set up Varnish accordingly. Don’t forget to add “mydomain2.com” in Magento settings /app/etc/env.php – http_cache_hosts

# /etc/apache2/sites-enabled/mydomain2.com.conf

# Added to mitigate CVE-2017-8295 vulnerability
UseCanonicalName On

Listen 8081
NameVirtualHost *:8081

<VirtualHost 127.0.0.1:8081>
        ServerAdmin webmaster@localhost

        ServerName mydomain2.com
        ServerAlias www.mydomain2.com

        DocumentRoot /var/www/html/pub

        <Directory /var/www/html/pub>
            Options FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        SetEnv MAGE_RUN_CODE "md_website"
        SetEnv MAGE_RUN_TYPE "website"

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

    SetEnvIf X-Forwarded-Proto https HTTPS=on
</VirtualHost>
# /etc/apache2/sites-enabled/mydomain2.com-le-ssl.conf

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerAdmin webmaster@localhost

        ServerName mydomain2.com
        ServerAlias www.mydomain2.com

        DocumentRoot /var/www/html

        <Directory /var/www/html>
            Options FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SetEnv MAGE_RUN_CODE "md_website"
        SetEnv MAGE_RUN_TYPE "website"

        SetEnvIf X-Forwarded-Proto https HTTPS=on

        SSLEngine on
        RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}

        ProxyPreserveHost       On
        ProxyPass               / http://127.0.0.1:80/
        ProxyPassReverse        / http://127.0.0.1:80/

        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateFile /etc/letsencrypt/live/mydomain2.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/mydomain2.com/privkey.pem
    </VirtualHost>
</IfModule>
# /etc/varnish/default.vcl

# VCL version 5.0 is not supported so it should be 4.0 even though actually used Varnish version is 6
vcl 4.1;

include "/etc/varnish/letsencrypt.vcl";

import std;
# The minimal Varnish version is 6.0
# For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'

# FD
backend default {
    .host = "localhost";
    .port = "8080";
    .first_byte_timeout = 600s;
    .connect_timeout = 300s;
    .between_bytes_timeout = 300s;
    .probe = {
        .url = "/health_check.php";
        .timeout = 2s;
        .interval = 2s;
        .window = 4;
        .threshold = 2;
   }
}

backend mydomain2 {
    .host = "127.0.0.1";
    .port = "8081";
    .first_byte_timeout = 600s;
    .connect_timeout = 300s;
    .between_bytes_timeout = 300s;
    .probe = {
        .url = "/health_check.php";
        .timeout = 2s;
        .interval = 2s;
        .window = 4;
        .threshold = 2;
   }
}

sub vcl_recv {
    if (req.http.host ~ "^mydomain2\.com$") {
        set req.backend_hint = mydomain2;
    } else {
        set req.backend_hint = default;
    }
}

acl purge {
    "localhost";
}

#...
# /etc/varnish/letsencrypt.vcl

vcl 4.1;

backend certbot {
    .host = "localhost";
    .port = "8080";
}

sub vcl_recv {
    if (req.url ~ "^/\.well-known/acme-challenge/") {
        set req.backend_hint = certbot;
        return(pipe);
    }
}

sub vcl_pipe {
    if (req.backend_hint == certbot) {
        set req.http.Connection = "close";
        return(pipe);
    }
}