Setting up: Fedora + Apache + PHP-FPM + MPM_Event

Yello folks, I typically don’t do setup guides, but this one is an exception because I didn’t find a “working” guide for this particular combination anywhere on teh interwebz.
The things I did find were mostly combinations of:

  • Fedora(Old Version)/(Other distribution) + Nginx + PHP-FPM
    or
  • (Some other distribution) + Apache/Nginx + PHP-FPM

None of these guides worked for me and I ended up with PHP’s White Screen of Death aka. WSOD.

First things first, some of you might ask why someone would move to this (weirdish?) setup from
something like the mpm_prefork + mod_php combination that has worked so well for ages.

  1. mpm_prefork is a resource hog compared to other threaded Multi-Processing-Modules (MPM) such as  mpm_worker and mpm_event
  2. mod_php although a very robust plugin, is no longer encouraged for use, the new standard is
    php-fpm or some other form of fcgi scripts, this separates the interpreter pool from the Apache
    workers and restricts things that the scripts can access (since they’re not running under the
    apache user)

Without further ado, the steps:

Install Apache

yum install httpd # Gotta start from the bottom

Install PHP-FPM

yum remove php #You don't need this
yum install php-fpm #Install php-fpm

Setup PHP-FPM

PHP-FPM runs as a separate service on localhost:9000
To start the service, you can do systemctl start php-fpm
Apache forwards all associated requests to PHP-FPM via mod_fcgi_proxy.

Assuming a stock installation, you’ll need to create a configuration file for php-fpm, to tell
apache what to put where.

Create a file called /etc/httpd/conf.d/php-fpm.conf and add the following lines to it,
explanations found in-line.

# Ensure all php files are handled by php-fpm
<FilesMatch .php$> RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ - [R=404,L]
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

# Public url to test php-fpm is working
# You need to uncomment the coresponding line to enable this option in
# /etc/php-fpm.conf
<Location /ping>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</Location>

AddType text/html .php

# Make index.php default in addition to index.html
DirectoryIndex index.php

To test that everything works well, do the following:

echo "<?php phpinfo() ?>" >/var/www/html/test.php

Then run try accessing the page via the browser at http://your.server.com/test.php.
If everything works as expected, you should see a table with the details of your php installation.
If you see a blank white screen aka the WSOD, check your apache and php-fpm error logs to see what
went wrong. They can be found in /var/log/httpd/error_log and /var/log/php-fpm/error.log

If all goes well you should have a working Apache + PHP-FPM installation.

Replacing MPM_Prefork with MPM_Event

MPM_Event has stayed the default MPM on Linux for a while despite the fact that there are better
performing and more efficient Multithreaded Process Managers out there.

The #httpd community on freenode strongly suggests using mpm_worker or mpm_event wherever one can.

If you don’t know what they are see here.
However if you do know what they are and want to switch from pre-fork because any of the following
reasons:

  • It’s slower to spawn
  • It consumes more resources
  • It gives lower performance vis-a-vis the other mpms

Then continue reading.

All this happens because it needs to create a new process per request and load all the modules into
the child for every request without sharing resources.

To use mpm_event make the following changes:

Open /etc/httpd/conf.modules.d/00-mpm.conf
Uncomment LoadModule mpm_event_module modules/mod_mpm_event.so
Comment LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

Next, Create a file /etc/httpd/conf.d/mpm_event.conf

<IfModule event.c>

#Number of children(servers) Apache will start with
StartServers       2

#This is the combined limit across all servers
MinSpareThreads    128

#This is the combined limit across all servers
MaxSpareThreads    256

#Default value, this limit is per child(server)
# This is the max you can increase ThreadsPerChild to
# without a requiring an httpd stop-start (not restart)
ThreadLimit        768

#Fixed number of threads each child(server) starts up with
ThreadsPerChild    64

#Max number of children(servers) Apache can spawn
ServerLimit        16

#Setting to ServerLimit*ThreadsPerChild + 1024
# Same as MaxClients in older versions of httpd
# Caps the Maximum value of ServerLimiit*ThreadsPerChild that can be set
# to without a requiring an httpd stop-start (not restart)
MaxRequestWorkers  3072
</IfModule>

Feel free to tune the values according to your hardware and server load.

After this simply restart the services:

# Note we don't do systemctl restart httpd
# because certain configs cannot be changed by a restart.
systemctl stop httpd
systemclt start httpd

systemclt restart php-fpm
Advertisements

One thought on “Setting up: Fedora + Apache + PHP-FPM + MPM_Event

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s