FastCGIExternalServer demystified

First Failure

Now that we’re all set, you can try to request http://fcgi.test.local in your browser.
This will most likely result in an error message:

No input file specified

Don’t worry, we’re going to deal with this problem later. For the moment, just request http://fcgi.test.local/index.php from your browser. You should see the familiar page with all the information PHP spits out when requested to do so.
Actually, it’s almost the familiar page. Most notably, the section “Apache Environment” should be missing. If you still see the Apache environment, you’re not running via FastCGI and you should check your setup before proceeding.

If everything worked as expected, you may now think “Hey cool. That was simple.”. Unfortunately it isn’t and I’ll show you why.

Remember the little line in our virtual host configuration, that enabled the external processing, supposedly of PHP scripts? I’ll repeat it here for clarity:

FastCGIExternalServer /srv/www/fcgi -host 127.0.0.1:9000

Remember also that I said this will cause all files residing in (or below, for that matter) that path will be processed by the external FCGI server? Unfortunately this is true to the word. Every file in or below that path will be processed by the external server. No matter whether it’s a PHP script (what we want) or a JavaScript file, a CSS file or some kind of graphics format. Everything will be processed by — well, thrown at — the external server.

Obviously, the PHP interpreter knowns nothing about interpreting JavaScript, CSS, GIF, JPG, you-name-it. You can easily test this by putting a GIF or JPG file into the directory and requesting it from withing your browser. The output will look something like this:

cougar_341

If you want to test for yourself, just copy any graphics file to the document root of your testing vhost and request it from within your browser. Clearly not what we want. But how to get to the desired result? That’s where the brain mangling starts.


{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.