Nginx for SSL Termination to Varnish & Apache Backend with WordPress

Just random stuff - Nothing to see here - Move along...

Nginx for SSL Termination to Varnish & Apache Backend with WordPress

System Architecture for Scaling Virtual Environment

All traffic should have ssl certs installed for each domain at nginx level.  Nginx is configured as ssl proxy only.  Certs are provided by Let’s Encrypt unless otherwise needed for other purposes.

(non-secure) Varnish (80) –> Apache (8080) –> Redis –> MariaDB

(secure) Nginx (as ssl proxy) (443) –> Varnish (80) –> Apache (8080) –> Redis –> MariaDB


Add Link here to Varnish CMS / WordPress, Joomla, Drupal config

Apache / PHP-FPM –> Redis –> MariaDB


WordPress Special Notes:

You have to tell WordPress that you are behind SSL and it will function properly. To accomplish this, I use the following code in wp-config.php

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {

Be sure to refresh everything once you make you change:

# systemctl restart varnish; systemctl restart nginx; systemctl restart php70-php-fpm; systemctl restart httpd 

You may find yourself needing to download a WP plugin to help with any other issues.

Here are a couple to try:


Misc Notes — Found (save) for possible varnish vcl changes

We run Varnish in between an F5 and Apache as well as use Nginx for ssl and load
> balancing in development, in conjunction with WordPress backends. You have to
> tell WordPress that you are behind SSL and it will function properly. To
> accomplish this I’d use the following code in wp-config.php
> if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
>        $_SERVER['HTTPS']='on';
> }
> You can then also set FORCE_SSL_ADMIN and FORCE_SSL_LOGIN however you see fit
> and it should work. I saw some updates not that long ago to support proxy
> headers but don’t believe they are fully supported yet.
> Jason
>> On Nov 2, 2015, at 12:37 PM, Carlos M. Fernández <cfernand at> wrote:
>> Hi, Phil,
>> We don't use Nginx but do SSL termination at a hardware load balancer,
>> with most of the work to support that setup done in the VCL, and something
>> similar could possibly apply to your scenario.
>> Our load balancer can use different backend ports depending on which
>> protocol the client requests; e.g., if the client connects to port 80 for
>> HTTP, then the load balancer proxies that to Varnish on port 80, while if
>> the client connects to 443 for HTTPS the load balancer proxies to Varnish
>> on port 8008. The choice of Varnish port numbers doesn't matter, just the
>> fact that Varnish listens on both ports and that the load balancer uses
>> one or the other based on the SSL status with the client (using the
>> command line option "-a :80,8008" in this case).
>> Then, in vcl_recv, we have the following to inform the backend when an SSL
>> request has arrived:
>> if ( std.port( server.ip ) == 8008 ) {
>>    set req.http.X-Forwarded-Proto = "https";
>> }
>> We also have the following in vcl_hash to cache HTTP and HTTPS requests
>> separately and avoid redirection loops:
>> if ( req.http.X-Forwarded-Proto ) {
>>    hash_data( req.http.X-Forwarded-Proto );
>> }
>> The backend then can look for that header and respond accordingly. For
>> example, in Apache we set the HTTPS environment variable to "on":
>> I have no knowledge of Nginx, but if it can be configured to use different
>> backend ports then you should be able to use the above.
>> Best regards,
>> --
>> Carlos.