Detailed walkthrough covering the setup of Nginx to work side-by-side with Apache and mod_php.

Nginx with Apache

Is your Apache web server (with mod_php or mod_perl) based application server suffering from memory outages or just freezing? Do you find it hard to keep up with millions of requests per hour? Then, read on. Find out why this happens and how Nginx can dramatically reduce the load on your application server with almost no change in your application code and only a few minor changes in your website templates.

Apache is Still a Good Application Server

Apache is still a good web application server when used wisely. It was not built to cope with today’s massive traffic. By architecture and for obvious reasons, Apache requires a process (or thread) for each of connections initiated by your visitors. This implies that if you have only 100 active visitors at some instance, you need (at the very least) 100×8 = 800 Apache processes running on your server. Now, if you have mod_php/mod_perl loaded with Apache, you need 30 MB memory on average per Apache processes. That turns out to be 24000 ~= 24 GB of memory – too high for even a high-end web server. Most likely you can’t afford that. Again, even if you have the budget, why waste it for nothing?

Some of us would prefer dropping mod_php for FastCGI or PHP-FPM to cut down the memory usage by a few megabytes. But, that doesn’t work around Apache’s architectural limitation that it requires a process per connection. And, if you love the additional features offered by mod_php, it’s integration with web server itself, then there’s no choice other than leaving Apache as the application server alone. Needless to mention existing mod_rewrite rules and other dependencies on Apache. Lastly, who likes to put application code/rules in Nginx server profiles?

Nginx and Apache Can Play Together

Our approach to the above problem is to let Apache do it’s job – as the frontend. And the, run Nginx side-by-side as your private CDN. There exists workarounds to common problems when Apache is made hidden behind a Nginx (reverse proxy), but, keeping Apache alone as the frontend is just elegant. In such configuration, you don’t have to look for dirty hacks to keep your application working.

The Recipe

  1. Get a free IP address for Nginx. We will use it to host domains like static.sforge.com instead of taking over www.sforge.com.
  2. Install Nginx and put your reserved IP inside the default server (_) block in nginx.conf file. Don’t start Nginx yet.
  3. Create a virtual server config file, i.e. static.sforge.com under Nginx. Make it listen only to the reserved IP and not interfare with Apache.
  4. Set the root of your Nginx virtual server to match Apache’s DocumentRoot. Thus, we just mirror the Apache site in Nginx.
  5. Configure the Nginx virtual server to allow only static files such as CSS, JS, PNG, GIF. Redirect rest of the requests to www.sforge.com.
  6. If you have Apache listening to all of your system IPs, configure it to listen only to the ones we need, and leave alone the Nginx IP.
  7. Make a subdomain under your DNS zone, such as static.sforge.com. Point it to the Nginx IP. Verify it with `nslookup static.sforge.com`.
  8. Start Nginx with `service nginx start`. Restart Apache with `service httpd restart`. Make sure that both of them are working under their respective IPs.

We are almost done. Try to access a static file, for example, http://static.sforge.com/images/logo.png. Nginx should serve it. Now, modify your website/application template(s) to point all static files to the Nginx server instead of the main server. For unmanaged templates, this is done best with a output buffer filter, which should specially tailored for your website. And now, your website is flying light, and still have Apache on its seat. Use an HTTP debugger like HttpWatch or Fiddler to verify.

Leave a Reply