Stop using PHP-FPM to argue using Nginx vs Apache

I often see “Apache vs Nginx” discussions appearing on reddit and some of the arguments people make are plain ridiculous. So now I want to address one that makes my eyes roll the post: PHP-FPM.

When Nginx first came into PHP world its popularity was mostly fueled by numerous benchmarks showcasing its speed vs a LAMP setup. You see Nginx didn’t have anything like Apaches’ mod_php and required the use of PHP-FPM, which indeed was a much faster way of processing PHP on multicore systems. The mistake people often did was to compare those setups and conclude that Nginx was just a better HTTP server.

Nginx is a great webserver, and its default setup is designed for performance, while the default Apache setup provides much more in terms of flexibility. But please don’t say that Nginx is better just because PHP-FPM is faster than mod_php, when you can easily setup Apache to use FPM too

One of the contributing reasons is that there is so many different configuration options in Apache that a person can easily misconfigure it. Apache has 3 MPMs: prefork, worker and event and even proxying request to the PHP-FPM server can be done in at least 3 entirely different ways. Nginx is easier to set up if you’re looking for a “good enough” solution, it’ll run pretty good out of the box.

At that time I thought people would eventually understand the actual difference and judge webservers on their own merits, but years passed and it’s still happening! So pretty much now we have 4 categories of developers:

  • People that use Apache because it comes with windows packages like WAMP and is very easy to setup on any Linux distro. These people don’t care how their PHP is executed at all
  • People that read a blog post that Apache isn’t cool anymore, installed Nginx with PHP-FPM and consider the first group to be inferior and less tech savvy.
  • People that are supporting a legacy app, are stuck with an old version of Apache ( maybe 1.3 even ), and think moving to Nginx would boost their performance sky-high
  • And there obviously is a portion of developers that actually have experience in both and can select the one that fits the task the best

The problem is that most of the “Apache vs Nginx comparison” posts are written by the first 3 groups of people. The fourth group has long ago realized that there is enough info on the internet to stop talking about it over and over.

The lessons you should take from this post are:

  • Try running Apache 2.4 with mpm_event and PHP-FPM using ProxyPass and see the results you get
  • If you have only a single core PHP-FPM won’t be faster than mod_php ( it’ll take a separate blog post to explain why )
  • In tech, never pick a single side, stay flexible
  • If you need performance use HHVM

15 Comments

  1. Benjamin Knigge

    January 2, 2015 at 12:34 pm

    I prefer Nginx because it’s capable of serving static content more quickly under heavy load while using less memory than Apache.

  2. Now you have clouded the waters with logic.

  3. First they (they, as in, the general set of developers) move from Apache to Nginx. Then the realize Nginx isn’t all that easy to configure and the lack of .htaccess _is_ actually a problem. And then they move back to Apache, but with the lessons learned from the Nginx setup: PHP-FPM.

  • ProxyPass is a security problem when used with .htaccess support, as it enables to proxy arbitray php-fpm instances (or other cgi implementations) and can be used to attack other websites on the same host.

    Do you have a solution for this problem? I see only one which I don’t like: libapache2-mod-fastcgi with FastCgiExternalServer.

    Example: (1) Create a readable PHP file (2) Let Apache proxy (fcgi:// in .htaccess) to that readable file with a cgi instance of another user (3) Execute own PHP file with another user, for instance read the database configuration from WordPress websites.

    • Dracony

      January 3, 2015 at 12:18 pm

      You can define separate php-fpm pools per website. And configurr them so that each pool runs as the correct user.
      I’ve done that with both nginx and apache so that there is no difference which one you choose.

      • Hello Dracony,

        you are right, but this doesn’t fix the problem. An attacker which is able to modify a the .htaccess files can define the php-fpm pool to use for attacks (with ProxyPass, fcgi://). That is the reason why other websites and users are attackable. One could argue, that binding the pools to UNIX sockets with random names could help. But the UNIX socket support for ProxyPass is not in the stable branch and this is security through obscurity.

      • I forgot to say that nginx is not affected as it doesn’t care for user defined configuration (like Apache with .htaccess).

        • Dracony

          January 3, 2015 at 11:55 pm

          You can restrict what can be overriden with AllowOverride directive

          • Do you know which options disallow the usage of proxies defined in .htaccess files? I found none and I need .htaccess support for custom mod_rewrites.

  • HI Dracony,

    Thanks for your blog post – I feel it will help alleviate confusion between the options of the two httpds.

    As for some feedback on the blog post itself, it’d be very beneficial to show an example of how to setup FCGI through Apache for people to begin testing out.

    Many thanks,
    Paul

  • After using Apache for years, I’ve come to hate the inconsistency and bugginess of mod_rewrite. If nothing else, the ease of setting up an Nginx install versus Apache is what convinces me.

  • Just wanted to drop a note to anyone looking for a solution to ProxyPass ignoring .htaccess rules… I literally spent 10 hours tonight finding this solution. When using ProxyPass, Apache will ignore any .htaccess since the proxy logic is executed in lieu of Apache searching the filesystem to match the request (and thus reading .htaccess files). To solve this problem while still using php-fpm, use the SetHandler directive in the vhost instead of ProxyPass:

    SetHandler “proxy:fcgi://127.0.0.1:9000” # this should match what php-fpm is listening to, of course

    So you get Apache with php-fpm and .htaccess! The “SetHandler” is supposedly an Apache 2.4.10 thing, but the CentOS/RHEL 2.4.6-19 package works fine with it–not sure what’s up with that, but I’m not complaining.

    Credit to this post (http://blog.famillecollet.com/post/2014/03/28/PHP-FPM-and-HTTPD-2.4-improvement) for the solution.

    • Ugh, the comment system removed the Apache config I posted around “SetHandler”. Check out the source link I posted for the syntax since I can’t post it here.

    Leave a Reply

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

    © 2024 Dracony

    Theme by Anders NorénUp ↑