What Apache/PHP configurations do you know and how good are they?

I wanted to ask you about PHP/Apache configuration methods you know, their pros and cons. I will start myself:

---------------- PHP as Apache module----------------

Pros: good speed since you don't need to start exe every time especially in mpm-worker mode. You can also use various PHP accelerators in this mode like APC or eAccelerator.

Cons: if you are running apache in mpm-worker mode, you may face stability issues because every glitch in any php script will lead to unstability to the whole thread pool of that apache process. Also in this mode all scripts are executed on behalf of apache user. This is bad for security. mpm-worker configuration requires PHP compiled in thread-safe mode. At least CentOS and RedHat default repositories doesn't have thread-safe PHP version so on these OSes you need to compile at least PHP yourself (there is a way to activate worker mpm on Apache). The use of thread-safe PHP binaries is considered experimental and unstable. Plus, many PHP extensions does not support thread-safe mode or were not well-tested in thread-safe mode.

---------------- PHP as CGI ----------------

This seems to be the slowest default configuration which seems to be a "con" itself ;)

---------------- PHP as CGI via mod_suphp ----------------

Pros: suphp allows you to execute php scipts on behalf of the script file owner. This way you can securely separate different sites on the same machine. Also, suphp allows to use different php.ini files per virtual host.

Cons: PHP in CGI mode means less performance. In this mode you can't use php accelerators like APC because each time new process is spawned to handle script rendering the cache of previous process useless. BTW, do you know the way to apply some accelerator in this config? I heard something about using shm for php bytecode cache. Also, you cannot configure PHP via .htaccess files in this mode. You will need to install PECL htscanner for this if you need to set various per-script options via .htaccess (php_value / php_flag directives)

---------------- PHP as CGI via suexec ----------------

This configuration looks the same as with suphp, but I heard, that it's slower and less safe. Almost same pros and cons apply.

---------------- PHP as FastCGI ----------------

Pros: FastCGI standard allows single php process to handle several scripts before php process is killed. This way you gain performance since no need to spin up new php process for each script. You can also use PHP accelerators in this configuration (see cons section for comment). Also, FCGI almost like suphp also allows php processes to be executed on behalf of some user. mod_fcgid seems to have the most complete fcgi support and flexibility for apache.

Cons: The use of php accelerator in fastcgi mode will lead to high memory consumption because each PHP process will have his own bytecode cache (unless there is some accelerator that can use shared memory for bytecode cache. Is there such?). FastCGI is also a little bit complex to configure. You need to create various configuration files and make some configuration modifications.

It seems, that fastcgi is the most stable, secure, fast and flexible PHP configuration, however, a bit difficult to be configured. But, may be, I missed something?

Comments are welcome!


Solution 1:

Running PHP via FastCGI will certainly give you the most flexibility. Not only can you safely use an mpm-worker Apache, you can even use another webserver altogether (e.g. nginx).

But even when staying with Apache, "PHP via FastCGI" is at the moment not one option, but at least two: mod_fastcgi, mod_fcgid. On top of that, you can either use dynamic, static, or external FastCGI processes; with or without suexec. And then there's PHP's internal FastCGI process manager, which is now replaced by the very nice PHP-FPM in PHP 5.3. All those options have different pros and cons and can lead to different problems.

Given the choice, I would pick mod_fastcgi with PHP-FPM at the moment, mostly because it allows for extremely versatile and stable setups.

Solution 2:

Not really answering your question, but I do not get this thing about FastCGI being difficult to configure. It is different that the other methods it should replace (mod_php, mod_python,...) so it may require rewriting a portion of the code. That can be the hard part, but for configuring Apache, at least, I find it is a cinch. As an example, I was testing a WSGI application in python, and I wanted to see how it performed with all the protocols that WSGI supports. Here is the virtual host file with the configurations for all the protocols (with mod_fastcgi):

<VirtualHost *:8888>
DocumentRoot "/home/test/"
#FastCGIExternalServer /home/test/wsgi -host 127.0.0.1:3333
#SCGIMount / 127.0.0.1:3333
FastCgiServer /home/test/wsgi/fcgi.py -idle-timeout 60 -processes 1
<Directory "/home/test/wsgi/">
    Options +ExecCGI +FollowSymLinks
    AddHandler fastcgi-script .py
    #AddHandler wsgi-script .py
    #AddHandler cgi-script .py
</Directory>
</VirtualHost>

It does not seems complex to me. Sure, FastCGI supports many options and it can be tweaked to death, but that is another matter.

To run is as a different user, use suexec and FastCGIWrapper, then it becomes:

FastCGIWrapper On
<VirtualHost *:8888>
SuexecUserGroup test test
DocumentRoot "/home/test/"
FastCgiServer /var/www/test/fcgi.py -idle-timeout 60 -processes 1
<Directory "/var/www/test/">
    Options +ExecCGI +FollowSymLinks
    AddHandler fastcgi-script .py
</Directory>
</VirtualHost>

And see this link for a custom php.ini, but you should be able to specify it with the -initial-env option, i.e.

FastCgiServer /var/www/test/fcgi.py -idle-timeout 60 -processes 1 -inital-env PHPRC=/blah/