The PHP circle: from Apache to Nginx and back

Mattias Geniar, Thursday, November 20, 2014 - last modified: Saturday, August 1, 2015

As with many technologies, the PHP community too evolves. And over the last 6 or 7 years, a rather remarkable circle has been made by a lot of systems administrators and PHP developers in that regard.

The A in LAMP

For many years, PHP was traditionally run in the "LAMP" stack; Linux, Apache, MySQL and PHP. Apache was the de facto webserver, often combined with PHP running as mod_php or as CGI. It worked, and in the mod_php scenario it was even a fast way of running your PHP apps. But permissions were always a pain, as everything is executed as the Apache user. apache2-mpm-itk tried to solve this, but was never a success.

So as time went by, more and more frustrations emerged with permissions in PHP applications and server setups. And then Nginx happened.

The rise of Nginx

A new webserver came into the picture, promising lightning speeds, extreme scalability, events instead of threads, ... it's here to scale your PHP app to the millions. That was the idea that many sysadmins had when they started migrating from the Apache webserver to Nginx.

And since Nginx doesn't have something like mod_php, an alternative had to be found to parse PHP. Back when PHP 5.2 was a thing, something called php-fpm emerged. It was, for the PHP world, revolutionary. Suddenly, there was a reliable way of separating the PHP processing from the webserver and it allowed you to properly use a webserver like Nginx for the first time.

Back in those PHP 5.2 days it still felt like a hack though, for systems administrators trying to manage the configs. Since 5.3 and upwards, php-fpm became officially supported in the core of PHP and became more mainstream, and the configs became more easy to manage.

But since Nginx doesn't have the AllowOverride option from Apache, that allows you to use .htaccess files to overwrite configurations for the webserver (this was, at the time, a large reason why Nginx became popular as well -- as AllowOVerride options can prove to be a real bottleneck). That means all rewrites, all caching headers, all additional gzip rules, etc. had to be defined in the Nginx configs. And those configs are usually managed by sysadmins, not developers. So PHP developers that do not manage their own servers, lose the flexibility of overwriting webserver settings from within their app.

As a result, PHP developers and sysadmins had to communicate more -- they had to coordinate their changes. I do believe the DevOps movement came, for the PHP community at least, as a result of this: what were normally 2 entirely separated worlds (Devs vs. Ops), now had to communicate and make changes accordingly. Both could give feedback on the requests of the other, since neither could make the change alone.

Alas, as time goes by, this becomes more of a hindrance than it adds value. PHP developers aren't as flexible anymore, as changes need to go through a sysadmin that needs to modify the configs -- assuming the PHP dev doesn't manage the server himself. And the novelty soon wears of, it all becomes an annoyance. It slows things down.

But at this time, the concept of running a webserver other than Apache, and running your PHP code as PHP-FPM pools, did become more of a commodity. We no longer considered mod_php to be the de facto standard.

Back to ye old faithful, Apache

It's the move to Nginx that though us a valuable lesson: there's a different way to run your PHP code. And as a PHP developer, you want to keep independent control of how the webserver, for your particular app, behaves.

I'm not saying Nginx is out of the picture. But I am seeing a movement away from Nginx, and back to Apache. Not the Apache configs that we made 6-7 years ago, with mod_php or CGI. But a config that incorporates the lessons we learned from the Nginx phase, of running PHP as the PHP-FPM daemon (or: multiple daemons) instead of a module in Apache. Of separating the webserver user from the PHP user, without sacrificing performance.

The Apache configs we make these days do still enable AllowOverride. They allow the PHP developer to manage their own rewrites, their own header configs and their own HTTP authentication settings, if they so chose to. And yes, Apache remains vulnerable to SlowLoris attacks (and many other types of attacks), whereas Nginx is more resilient. Yes, Apache has its downsides -- it sure does. But it has a lot of great features, and the .htaccess files with AllowOVerride are one of them.

The circle of moving away from Apache, to alternative webservers like Nginx and slowly moving back to Apache, is something I expect we'll see all the time. In a few years time, we'll probably move to yet another method of running PHP and configuring our webservers.

So, Nginx is a no-go?

Absolutely not.

While I see a movement of slowly backing down from Nginx, there are still great values in the webserver: the configs need to be managed by sysadmins, they enforce communication between Devs and Ops. The webserver is entirely different from Apache, with its own pros and cons.

Every project needs to make the choice of webserver, and for some Nginx is the best option, for others Apache or yet another webserver. This has always been the case, but in the last year we've seen more decisions that fall back to Apache than chose to go with Nginx.

Hi! My name is Mattias Geniar. I'm a Support Manager at Nucleus Hosting in Belgium, a general web geek & public speaker. Currently working on DNS Spy & Oh Dear!. Follow me on Twitter as @mattiasgeniar.

Share this post

Did you like this post? Will you help me share it on social media? Thanks!


Lennie Thursday, November 20, 2014 at 07:33 - Reply

For one old project, I already had Apache with prefork and mod_php running, then the site became very popular and had to change things quickly without breaking the site. I placed nginx in front of it. nginx handles the connections, and most static files.

For my latest project I choose: Apache Worker MPM with PHP-FPM and Vagrant in front of it. It’s a WordPress site with W3 total cache. Yes. .htaccess was the reason I choose that solution.

Using Apache solves the .htaccess problem, but one thing is still missing. You can’t set php_value in .htaccess with PHP-FPM.

Some day soon this site will need HTTPS.

I’m hoping the Vagrant developers will add SPDY, HTTP/2 and SSL/TLS to their software eventually. For now I’ll need an other workaround that is I’ll need an other piece of software, nginx or haproxy in front of Vagrant.

    Mattias Geniar Thursday, November 20, 2014 at 09:59 - Reply

    When you say Vagrant, I assume you mean Varnish – right?

    For me, SPDY/SSL isn’t necessary in Varnish. There’s plenty of reverse proxy configs (nginx/apache/pound/…) that make it easy to setup and manage the SSL layer in front of Varnish.

      Lennie Thursday, November 20, 2014 at 10:06 - Reply

      Yeah, sorry. I meant Varnish. Silly mistake. I was awake far to early this morning.

      Having all these layers is starting to feel a bit hackish.

      Then again in this new microservices world, maybe it’s the new normal ! :-)

Bert-Jan Thursday, November 20, 2014 at 14:40 - Reply

You haven’t highlighted the possibility of switching Apache to worker-mode instead of prefork-mode. Iirc the performance difference can be quite significant. Also.. wouldn’t switching away from prefork-mode make it a lot less (maybe even completely) vulnerable to slowloris ?
I noticed in Apache 2.4 there are some configs settings to define a few different kinds of request timeouts.. that’s probably also meant to serve as a (rudimentary) countermeasure against slowloris.

Leave a Reply

Your email address will not be published. Required fields are marked *