Why do we need all these servers?

Most web applications are very slow, escpecially if under stress. Magento is one of those slower ones, but we cannot blame it for being slow, because this is the price we have to pay for its huge amount of features and its great flexibility.
We can handle performance issues by preventing same pages (or parts of them) to be generated more than once by caching them. Magento's and TYPO3's caching frameworks are great for this purpose, but when using a reverse proxy like Varnish we additionally can improve performance dramatically.
Plus Varnish offers some fancy features like load balancing, health checks and will deliver cached pages if your backend (Apache in my case) might not be available.

But: Varnish does not handle SSL connection. Read this great article for some good reasons why Varnish will probably never handle SSL by itself.
This is why we need some other server to act as a HTTPS-to-HTTP wrapper. You might use Stunnel or Pound for that purpose. Or Nginx, which comes with some more fancy features, that might come handy.

You're free to run Nginx, Varnish and Apache on the same server. In a real production setup you would probably have different servers for this the reduce the risk of failure. Additionally you might use this setup to use multiple servers each running Apache for horizontal scaling. Make sure to configure your firewall that only the Nginx server will be accessible from outside.

Configuring SSL

First of all you should have a valid SSL certificate setup on your server. Nginx is a very picky, but this blog post will help you setting up everything if you're experiencing problems.

The big picture

Nginx configuration

Nginx will accept all incoming http and https connections (on port 80 and port 443). It will process ssl and pass the decrypted request to its backend, that is Varnish in our case. For backup purposes Nginx can be configured to use Apache directly if Varnish should't be responding.

The trick with SSL is, that an additional header HTTPS "on" will be set, that will be detected by Apache later to tell the application that we're in a SSL reques.

Here is a minimum example of a Nginx configuration file for this setup:

192.168.178.28 is the "public" ip address in my test setup. I'm running Ubuntu in a VirtualBox as my development server. Of course you need to replace the IP addresses, server names and port configurations to your setup in this and in the following configuration snippets.

upstream varnish {  
    server localhost:6081;  
    server localhost:8080 backup;  
}  

server {  
    listen       192.168.178.28:80 default;  
    server_name  www.myshop.com;  

    location / {  
        proxy_pass [varnish](http://varnish);  
        proxy_set_header Host $http_host;  
        proxy_set_header X-Forwarded-Host $http_host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        proxy_set_header HTTPS "";  
        proxy_hide_header X-Varnish;  
        proxy_hide_header Via;  
    }  
}  

server {  
    listen       192.168.178.28:443;  
    server_name  www.myshop.com;  

    ssl                  on;  
    ssl_certificate      server.crt;  
    ssl_certificate_key  server.key;  

    ssl_session_timeout  10m;  

    ssl_protocols        SSLv3 TLSv1;  
    ssl_ciphers          ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM;  
    ssl_prefer_server_ciphers   on;  

    location / {  
        proxy_pass [varnish](http://varnish);  
        proxy_set_header Host $http_host;  
        proxy_set_header X-Forwarded-Host $http_host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        proxy_set_header HTTPS "on";  
        proxy_hide_header X-Varnish;  
        proxy_hide_header Via;  
    }  
}

Varnish configuration

This snippet shows only the code handling the setup. You need to add our vcl code in there. You might want to have a look at the basic Varnish I'm proposing for my Aoe_Static module (also check GitHub).

In this example I defined two backends, each pointing to an apache server. Additional there is a "meta"-backend that does a round-robin load balancing on the actual ones. Read this documentation for more detailed information on load balancing with Varnish.

In a simple development environment setup you will probably have only one Apache as backend server for Varnish. Then remove the round-robin part in the snippet below and point the default backend to your single one.

backend myshop1 {  
    .host = "127.0.0.1";  
    .port = "8080";  
}  
backend myshop2 {  
    .host = "192.168.178.29";  
    .port = "8080";  
}  
director myshop round-robin {  
    {  
        .backend = myshop1;  
    }  
    {  
        .backend = myshop2;  
    }  
}  

# Append your varnish configuration (sub vcl_*) here...  

Apache configuration

And last, but not least there is the Apache configuration. If the request header "HTTPS" is "on" an environment variable "HTTPS" will be set to "on". This is what Apache and other server would also do when configured to actually handle SSL requests. TYPO3 and Magento are considering this environment variable when detecting if the current request is an SSL request. (This might be important for link generation or different caching behaviour).

Make sure that "on" is written in lowercase letters. Sadly Magento Enterprise Edition's FullPageCache won't be able to detect SSL requests if the value is in uppercase letters.

<VirtualHost *:8080>  
    ServerName www.myshop.com  

    # SSL detection inside PHP (reverse proxy nginx sets HTTPS header if using SSL)  
    SetEnvIf HTTPS on HTTPS=on  

    # Add your configuration here ...  
</VirtualHost>

Related blog posts

Comments

This website uses disqus for the commenting functionality. In order to protect your privacy comments are disabled by default.

Enable Comments