FastCGIExternalServer demystified

Separating Apache and PHP has some advantages. Faster delivery of non-PHP content, lesser load on the servers to name just the most obvious ones. That’s why you can find this kind of setups mostly at smaller ISPs. To really benefit from the separation of Apache and PHP, however, you’d need to move PHP to completely seperate servers.

That’s where

FastCGIExternalServer

comes into play. In theory this Apache configuration directive allows you to specify an external server where all requests for PHP scripts (or any other resources you define) will be sent to. But where you’ll find plenty of documentation about how to install a FastCGI server on the local machine, the documentation about how to use an external server is almost non-existant. And the official documentation doesn’t really help and neither does the FAQ. Or would you find this helpful:

What is the path used with FastCGIExternalServer?

Since all FastCGI directives are global (they are not configured in a server context), all FastCGI paths map to the filesystem. In the case of external servers, this path does not have anything to do with the file system; it is a virtual file system path. Since the connection between mod_fastcgi and the FastCGI app is by a socket (unix or tcp), mod_fastcgi does not care where the program is (it could be on a completely different machine). However, mod_fastcgi needs to know when a hit is calling for an external app, so it uses this path as if it were a local filesystem path. Apache translates a request URI to a filesystem path.

Most ironcally, it’s exactly the path mentioned above that causes most users to give up on

FastCGIExternalServer

. Ok, so let’s get our hands dirty. Follow me into the abyss of weird logic and software bugs to finally get your external PHP server up and running. On the way you’ll learn that nothing is as it seems and that the FAQ entry quoted above is misleading at best.

[ Continue reading » ]

{openx:6}

11 thoughts on “FastCGIExternalServer demystified

  1. Pingback: External FastCGI With Apache « IT Know-It-All

  2. Mattes

    Great article, but how did you solve the problem with the trailing index.php?
    If I call the domain, the php file are provided as a download.
    If I add index.php, I get redirected to /virtualpath/index.php/ which results in a 404. Everything else works like a charm…

  3. Stefan Rubner Post author

    Can’t really say what the problem with your setup is. Either it’s a missing “DirectoryIndex index.php” statement in the htpd.conf file or your settings for calling the FCGI process are a bit borked. If you could post the settings for your vhost, maybe I could help more then.

  4. Michael

    Has anyone gotten this to work – with a host that is not local? i.e. not localhost 127.0.0.1

    I’m doing a project where I want to completely separate Apache from PHP-FPM.

    But I can’t get it to work. When using Apache & PHP-FPM on the exact same physical host – same OS instance – works great.

    The moment I switch the host line value for FastCGIExternalServer to external IP – I get 404 errors.

    Example:
    10.0.0.2 = Apache server only. (physical box#1)
    FastCGIExternalServer // -host 10.0.0.3:9000 -pass-header Authorization

    10.0.0.3 = php-fpm server (physical box#2)

    I see the request come into the php-fpm access logs ( after I turned them on ). But they show remote server requests like this:

    10.0.0.2 – 30/Jun/2012:17:13:37 -0700 “GET /phpinfo.php” 404 – 2.472 768 0.00%

    Whereas if I run Apache on the same machine as php-fpm the access log looks like this. ( and it works )

    10.0.0.3 – 30/Jun/2012:17:05:15 -0700 “GET /phpinfo.php” 200 /(full path on host to htdoc root)/(name of virtual host)/phpinfo.php 23.373 768 85.57%

    Is there something simple I’m missing? perhaps more than just the Authorization header is needed?

    -Michael

  5. Stefan Rubner Post author

    Michael, I’m running around 250 instances with a non-local setup and they’re working perfectly. The thing you have to watch out for is that the PHP-FPM instances you’re running have to have access to the PHP files under the very same path the web-server that is forwarding the requests is using. So you have to either copy the files over to the server or use a central shared storage to make it work. If you want me to have a closer look, just drop me an email.

  6. Michael

    Stefan, thank you! Scouring the net – I found only 1 barely readable ( bad grammar ) statement that network filesystems may be needed.

    I took your great recommendation and a bit of NFS here and there… and presto… it’s all working… well…

    Sorta…

    I’ll need to try a few more apps… but so far… the FPM is REALLY SLOW… at least by comparison to libphp ( mod_php w/XCache ).

    Quick Test using OpenX 2.8.9 – 9.4 seconds to get the homepage to render? When I put in a username/password and hit submit – it took another 14 seconds to login. With mod_php this is like 2 seconds or so. I assume I must have done something wrong.

    Here’s what I see in the FPM access log.

    – 13/Jul/2012:22:20:12 -0700 “GET /www/admin/index.php” 200 /www/admin/index.php 9489.107 29440 6.32%

    – 13/Jul/2012:22:20:22 -0700 “GET /www/admin/assets/min.php?g=oxp-css-ltr&v=2.8.9” 304 /www/admin/assets/min.php 19.750 1280 0.00%

    – 13/Jul/2012:22:20:22 -0700 “GET /www/admin/assets/min.php?g=oxp-js&v=2.8.9” 304 /www/admin/assets/min.php 18.118 1280 0.00%

    Anyone have any hints on performance? I’ve tried no op-cache and I’ve tried XCache no difference – both ~10 second times… I’m going to try APC next.

    -Michael

  7. Michael

    Well APC made no difference.

    Is FastCGI w/php FPM – really 5X slower than – Apache w/libphp ?

    Very odd.

    18/Jul/2012:12:51:48 -0700 “GET /www/admin/index.php” 200 pathtowwwroot/www/admin/index.php 10991.318 6656 4.00%

    4% CPU; yet it takes 10.991 seconds? vs. Apache w/libphp – takes 1.8 seconds?

    -Michael

  8. Stefan Rubner Post author

    This really looks strange. Would love to have a look at it. If you want me to, drop me an email at stefan [at] whocares [dot] de.

  9. Michael

    Hello Stefan,

    Thank you for the great information on your blog, and I very much appreciate your offer of some help.

    On my end – I figured out the issue… but I’m not really happy with what I found and would love to hear if you have any pointers.

    10.0.0.2 = Apache server. (physical box#1)
    FastCGIExternalServer -host 10.0.0.3:9000 -pass-header Authorization

    10.0.0.3 = PHP-FPM Server (physical box#2)

    Apache 10.0.0.2 – with mod_php ( libphp ) + XCache = simple test using OpenX dashboard screen = 2.38 seconds.

    Apache 10.0.0.2 using FastCGI -> to 10.0.0.3 PHP-FPM Server w/APC ( using NFS mount from 10.0.0.2 to 10.0.0.3 for www-docroot ) = same simple test using OpenX dashboard screen = 10.38 seconds. ( about 4X slower ).

    However…

    Loading a 2nd Apache on 10.0.0.3 – with FastCGI to PHP-FPM Server w/APC (localhost) – made copy of OpenX site so everything was local on 10.0.0.3 = same simple test using OpenX dashboard screen = 2.55 seconds. So very slightly slower – I’ll retry with XCache on the localhost PHP-FPM and see if the times match up… but it’s close enough.

    In effect.

    When Apache is on 10.0.0.2 – using the connection string – FastCGIExternalServer -host 10.0.0.3:9000 – performance is 4X worse.

    When I just make another Apache on 10.0.0.3 with – FastCGIExternalServer -host 127.0.0.1:9000 – performance is very comparable to – libphp (mod_php). And since this was only a single user test… I expect that under load – PHP-FPM will do much better.

    No idea why using a remote host is so much slower.

    I’ll keep playing around. But this is rather disappointing.

    BTW – did you or anyone else figure out how to get SETUID to work?

    Apache with FastCGIWrapper ( suexec ) seems like the best solution and amusingly works fine with FastCGI – when I use FastCGIConfig. But I just get 404 errors when I try and use FastCGIExternalServer – has anyone run into and figured out a solution for using FASTCGIWrapper with FASTCGIExternalServer?

    -Michael

  10. thomas.night

    To fix $_SERVER[‘SCRIPT_NAME’] you can youse prepend file like this:

    save it for example in /fcgi/prepend.php .
    In your php.ini ( /etc/php5/cgi/php.ini ) add:

    auto_prepend_file = /fcgi/prepend.php

    Thank you for the awsome manual!

  11. Christian Loock

    Unfortunately all I get is:

    Forbidden

    You don’t have permission to access /virtualpath/index.php on this server.

Comments are closed.