If your production server is running Apache, mod_php and mpm prefork and you want to upgrade to MPM Event and PHP-FPM, then it is just a few steps. For this guide, we have tested the workflow on a server which is running PHP 7.2 (which is an old version). You can follow similar steps for any present version of PHP, only modify the version number. We have tested that restarting the server after the completion of the whole workflow is sufficient. So, even on a production server, the downtime will not be significant.
This guide is for operating a single site on a 16GB dedicated or cloud server.
Steps to Install Apache MPM Event and PHP-FPM
This command will install all the required components to run PHP-FPM:
---
1 | apt-get -y install apache2-doc apache2-utils libapache2-mod-php php7.2 php7.2-common php7.2-gd php7.2-mysql php7.2-imap php7.2-cli php7.2-cgi libapache2-mod-fcgid apache2-suexec-pristine php-pear mcrypt imagemagick libruby libapache2-mod-python php7.2-curl php7.2-intl php7.2-pspell php7.2-recode php7.2-sqlite3 php7.2-tidy php7.2-xmlrpc php7.2-xsl php-imagick php7.2-gettext php7.2-zip php7.2-mbstring php-soap php7.2-soap php7.2-fpm |
Please change the version number of PHP from 7.2 to your version (such as 8.2). You can search the repository for modules for your version of PHP:
1 | apt search php8.2 |
First, disable the mod_php
:
1 | sudo a2dismod php7.2 |
Next, disable mod prefork
:
1 | sudo a2dismod mpm_prefork |
Enable mpm_event
:
1 | sudo a2enmod mpm_event |
Activate the required Apache2 modules:
1 2 3 4 5 | sudo apt install php7.2-fpm sudo apt install libapache2-mod-fcgid sudo a2enconf php7.2-fpm sudo a2enmod proxy sudo a2enmod proxy_fcgi |
Now check the below configuration file:
1 | cat /etc/apache2/conf-enabled/php7.2-fpm.conf |
This must not be empty. Run configuration test and restart Apache:
1 2 | sudo apachectl configtest sudo systemctl restart apache2 |
Now your site should be running on PHP-FPM.
1 | sudo apachectl -M | grep 'mpm' |
output will be as follows:
1 | mpm_event_module (shared) |
Check the proxy module and FastCGI:
1 2 3 4 | sudo apachectl -M | grep 'proxy' ## output # proxy_module (shared) # proxy_fcgi_module (shared) |
Create a PHP info webpage and check from browser:
1 | sudo nano /var/www/html/info.php |
Paste this content:
Do not forget to delete this file after checking.
To prevent the server from HTTPOXY attacks, we will create the httpoxy.conf
file:
1 | nano /etc/apache2/conf-available/httpoxy.conf |
Paste this configuration:
1 | RequestHeader unset Proxy early |
Save the file. Enable the HTTPOXY configuration file and restart Apache:
1 2 | a2enconf httpoxy sudo systemctl restart apache2 |
Optimizing Apache2 mpm_event and PHP-FPM
Open the mpm_event
configuration file:
1 | nano /etc/apache2/mods-enabled/mpm_event.conf |
Add/modify to reflect the below content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <IfModule mpm_event_module> KeepAlive On KeepAliveTimeout 5 MaxKeepAliveRequests 128 ServerLimit 10 StartServers 4 ThreadLimit 128 ThreadsPerChild 128 MinSpareThreads 256 MaxSpareThreads 512 MaxRequestWorkers 1280 MaxConnectionsPerChild 2048 </IfModule> Test it: <pre> cd ~ apt install python wget https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py chmod a+x ps_mem.py sudo python ps_mem.py |
On my test 16GB dedicated server, it was sucking 2GB RAM:
1 2 3 4 5 6 7 8 9 | Private + Shared = RAM used Program ... ... 113.3 MiB + 11.3 MiB = 124.6 MiB apache2 (5) 1.3 GiB + 652.9 MiB = 2.0 GiB php-fpm7.2 (31) 3.0 GiB + 390.5 KiB = 3.0 GiB mysqld --------------------------------- 5.3 GiB |
Open the PHP-FPM configuration file:
1 | nano /etc/php/7.2/fpm/pool.d/www.conf |
Adjust these parameters:
1 2 3 4 5 6 | pm = dynamic pm.max_children = 100 pm.start_servers = 20 pm.min_spare_servers = 10 pm.max_spare_servers = 30 pm.process_idle_timeout = 10s; |
You can adjust the values to higher later after reading various documentation and guides available all over the internet. We have tried to deliver a balanced setting.
Restart Apache and PHP-FPM:
1 2 | sudo systemctl restart php7.2-fpm sudo systemctl restart apache2 |
Enable HTTP/2 from virtual host file and test it.
Normally, you’ll not need more optimization for running a single domain. To add multiple websites (separated from each other), you have to add a new Apache user, and add a new configuration file at /etc/php/7.2/fpm/pool.d
.