Drupal 7 + HTTPS + Nginx + Varnish + Apache + Boost + APC + Securepages + Drupal

If you happen to develop large sites in Drupal, you might fall upon a case like this one, where different servers (namely at least one reverse proxy and one web server) interact, causing a series of chain reactions every time you change something. It might be frustrating, at times, to try and boost a coordinated system like this, and end up getting your users frustrated because part of it doen't work, when the rest (the part that *does* work) is super-fast. Come on, you deserve some praise! Let's explain a little bit about what requirements might lead to this system... First of all, you want a website. You don't want to play with php-fpm yet, so you decide to use Apache + mod-PHP. Great. Then you want to boost the page interpretation time a little bit, so you decide to use APC. Nothing wrong there. You now have Apache + PHP + APC + Drupal in line. Then you want to make sure anonymous users get pre-generated pages to go even faster. You add the Boost module to the loop. You now have Apache + Boost + PHP + APC + Drupal. Then you want to speed up loading small static resources, like icons and stuff. You decide to add Varnish in front of the queue. You now have Vanish + Apache + Boost + PHP + APC + Drupal. And then comes the late requirement for HTTPS... Damn... Varnish doesn't support HTTPS!? Man, and now what? Well... you can use Nginx to decipher HTTPS and handle things over to Varnish to follow in the normal queue. You now have HTTPS + Nginx + Varnish + Apache + Boost + PHP + APC + Drupal. And finally, your customer tells you that, because of the extra load (between 20% and 400%) generated by the ciphering to HTTPS, he only wants specific pages to be HTTPS. Apart from the mess in redirecting pages to HTTP when they shouldn't be HTTPS (which can be done in Nginx's config), you will also need to define rules to send HTTP pages to HTTPS when they should be secure. You can do that with Drupal's Securepages module. You finally have your (rather) complete schema of HTTPS + Nginx + Varnish + Apache + Boost + PHP + APC + Securepages + Drupal. Here is a list of things to think about when doing this:
  1. the Boost module had a bug in early 2012, which didn't define the DRUPAL_UID cookie very consistently (see previous article on this blog). Because of that, users might loose their session "from time to time" (which is more than frustrating for both you and your customer)
  2. in the specific case of requesting pages to be HTTPS without being logged in (which has the effect of not generating  Drupal connection cookie), the user will first get to Varnish, which will pass on to Apache, which will pass on to Drupal (I'm skipping a few steps here), which will send a HTTP Redirect to Varnish and Varnish will (cache it and) pass it to the user. The user (the user's browser, in practice) then calls the same URL as HTTPS. Now Nginx takes over for deciphering HTTPS into HTTP before passing it on to Varnish. When Varnish rceives the call, whether it is cached or not, the return value it sends is a 301 Redirect, to the same URL as HTTPS. And so you now are in a loop.