Using Nginx Alongside Apache to Serve Static Content

Using Nginx Alongside Apache to Serve Static Content

There are a lot of blogs out there talking about installing Nginx as a proxy in front of Apache. Simply having Nginx serve all the static content and then proxying PHP, etc. back to Apache for it to deal with those requests.  There are also lots of posts out there dealing with replacing Apache with Nginx entirely.  The situation I found myself in was need to improve performance (see Google Pagespeed about serving static content from a cookieless domain, etc.) on our web servers while saving money and thinking about the fact that in the future we will be transitioning our static assets to a CDN.

So with this eye towards the future I came up with the following solution. Run Nginx side by side with Apache on  a different port.

Apache & Nginx Diagram

The diagram shows how this works.  You need a second domain with a completely different IP.  Yes this means having to purchase a second IP, but remember, we are working towards the future where we are going to be using a CDN, so this isn’t a big deal. The reason for the second IP is that it makes the setting up the translations on the firewall a lot easier.  Once you start defining mappings like 80 to 8080 on an IP, you need to specify all ports that are open for that domain and we don’t really want to have to do that for our main domain. The static domain is only going to be for that single task, so specify one port on that is easier than specifying multiple ports on the main domain.

Now on the code side what I do is the following:

Bootstrap:

if ($_SERVER['HTTPS'] != 'on') {
    define('STATIC_URL', 'staticdomain.com');
} else {
    define('STATIC_URL', '');
}

Apache is currently serving all static content and I haven’t configured Nginx to use our SSL cert yet. This means that we want the static content to be server via Apache for secure connections. Secure connections only account for a small part of our traffic so that is OK for now. Ideally in the future I will want to have Nginx serve static content for secure connections.

Layout:

   // styles
   $view->headLink()->appendStylesheet(STATIC_URL.'/css/layout.css');
   // scripts
   $view->headScript()->appendFile(STATIC_URL.'/scripts/jquery.min.js');

In your layout you simply prepend the static url to all static content such as stylesheets and JavaScript.

Views:

   <p><strong>This is my static content</strong></p>
   <img src="<?php echo STATIC_URL ?>/images/image.png"/>

In all your views, you will also need to prepend the static url to all images.

Conclusion:

This is a great way to open up some headroom on your server, save money, serve you static content faster and be able to transition to a CDN in the future.  We it comes time for us to implement a CDN, all it will take is changing the static url in the bootstrap.