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.
mpm_prefork
is a resource hog compared to other threaded Multi-Processing-Modules (MPM) such as mpm_worker
and mpm_event
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
mpm
s
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