FastCGIExternalServer demystified

Alias me

To make the thing fly work, we need to make one last modification to our virtual host configuration:

<VirtualHost *>
    ServerName    fcgi.test.local
    FastCGIExternalServer /fcgi/www/fcgi -host 127.0.0.1:9000
    AddHandler php-fastcgi .php
    Action php-fastcgi /virtualpath
    Alias /virtualpath /fcgi/www/fcgi
    DocumentRoot /srv/www/fcgi
    <Directory /srv/www/fcgi>
        AllowOverride   All
        Order           Allow,Deny
        Allow           from all
    </Directoy>
</VirtualHost>

The

Alias

directive instructs Apache to remap every call to /virtualpath to the new location /fcgi/www/fcgi and of course append all the stuff that was trailing the original path before. And alas, we now have a clean call to where our

FastCGIExternalServer

resides.

Recap:
To seperate our PHP code from the other stuff under the document root, we need to point the

FastCGIExternalServer

to some directory other than the original document root. To get to that very directory, we need to add a new Handler with

AddHandler

so Apache knows that files with the extension .php are to be treated specially. Next we have to create the

Action

we named as the handler for our PHP code. And finally we have to redirect the action to where our new FastCGIExternalServer thinks is his area of responsibility.

Do you spot the flaw?

Ok, that was easy: The (again, not so) virtual path for the

FastCGIExternalServer

doesn’t exist yet. So let’s fix that one, too:

mkdir -p /fcgi
cd /fcgi
ln -s /srv/www

This will provide a symbolic link to our document root. The only reason for having it really is the need to seperate our PHP code from all the other stuff. So essentially we came back full circle here just to make Apache and

FastCGIExternalServer

happy. Funny, isn’t it?

For must use cases, we’re finished here. However, there are some PHP apps out there that use deprecated internal variables and will refuse to work even after we fixed up almost everythin for them. To fix those remaining apps, too, we unfortunately need to modify either the app or PHP itself. So let’s deal with those, too.


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