Switching from Apache2-MPM-Prefork to Apache2-MPM-Worker with mod_fcgid

Apache is one of the most used webservers worldwide, and if you’re hosting a website somewhere the odds are you are using it. Those of us which use a VPS or a Dedicated server to host their project might notice that as the traffic to their site rises their server slowly starts to eat up the RAM and respectively starts getting downtimes at peak traffic. At thas point people start optimizing mysql, installing php-apc, enabling mod_expires, but sometimes the outages just persist.

Apache2 however comes with two MPMs: Prefork and Worker.
Prefork MPM which is the default MPM, and probably the one you`re using is considered to be thread safe. It uses multiple child processes with one thread each handling one connection at a time.
Worker MPM the one we`re interested in, uses many child processes with many threads each, handling one connection at a time.
The big deal about Worker MPM is that it uses significantly less memory which is great for high traffic websites, so if all apache libraries you’re using are thread safe(for example mod_php is not) it is probably a good idea to switch from Prefork to Worker.
If you`re not sure which MPM your server uses you can check by typing the following command in the command line

root@somehost# apache2 -l

And the output you’re looking for is:

Compiled in modules: core.c mod_log_config.c mod_logio.c prefork.c http_core.c mod_so.c

If you’re using prefork you should see prefork.c in the output of the command, however if you see worker.c this article isn’t for you :)

Now the actual how-to switch from Prefork to Worker with mod-fcgid tutorial:

*Note that these steps are for Debian and Probably Ubuntu the syntax of these commands will probably be different in CentOS or the other popular OSes

Step1: Stop the apache process

root@somehost# service apache2 stop

Step2: Install Apache2-MPM-Worker

root@somehost# apt-get install apache2-mpm-worker

Step3: Install mod_fcgid and PHP5

root@somehost# apt-get install libapache2-mod-fcgid php5-cgi

Optional: If Apache2 was installed with PHP5 as module disable it(thread safety..remember)

root@somehost# a2dismod php5

Step4: Enable the following modules if they’re not already enabled

root@somehost# a2enmod rewrite root@somehost# a2enmod include root@somehost# a2enmod fcgid

Step5: Open php.ini and add “cgi.fix_pathinfo = 1″ at the end of the file

root@somehost# vi /etc/php5/cgi/php.ini

Step6: Create a file called “php-fcgi-starter” one level above the www folder of your site.

In our example our site’s files will be located at “/home/oursite/www” and we’ll create the file at “/home/oursite/”

root@somehost# vi /home/oursite/php-fcgi-starter

And insert the following contents:

export PHPRC
exec /usr/lib/cgi-bin/php

Save the file by pressing “:w” and “Enter” and quit(“:quit” and Enter)

Step7: Fix the permissions of the php-fcgi-starter file.

*Note that this step is very important. If you don`t do this properly you’ll probably get
“(104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server Premature end of script headers”
The first thing you need to do is find your apache2 user by typing:

root@somehost# ps aux | grep apache2

The output will be something similar to:

www-data 19335  0.0  0.1   7084  2160 ?        S    07:24   0:00 /usr/sbin/apache2 -k start
www-data 19336  0.0  0.2 231960  5276 ?        Sl   07:24   0:01 /usr/sbin/apache2 -k start
www-data 19338  0.0  0.2 230976  5240 ?        Sl   07:24   0:01 /usr/sbin/apache2 -k start

The apache2 user is in the first column, in this case “www-data”
Now once you know this enter

root@somehost# chown www-data /home/oursite/php-fcgi-starter
root@somehost# chmod 775 /home/oursite/php-fcgi-starter

Step8: Edit your apache2 vhost

<VirtualHost *:80>
    ServerName somesite.com
    ServerAlias www.somesite.com
    ServerAdmin some@email.com

    DocumentRoot /home/oursite/www/
    <Directory /home/oursite/www>
        Options +ExecCGI
        AllowOverride All
        AddHandler fcgid-script .php
        FCGIWrapper /home/oursite/php-fcgi-starter .php
        Order allow,deny
        Allow from all

Step9: Restart Apache2

root@somehost# service apache2 restart

And that is it you now have a working Apache2-MPM-Worker with mod_fcgid