In a previous article from over 5 years ago, we advocated the use of Apache MPM Worker Threaded Server with fcgid over Apache's mod_php.
That was for serveral reasons, including faster handling of static files by Apache threaded server, and lower memory utilization since PHP is not embedded in every Apache process.
However, there were some drawbacks, mainly that APC opcache cache is not shared, and each process has to have its own copy.
But we don't have to settle for the above trade off anymore, because there has been a better alternative for some time now: Apache MPM Worker Threaded server + PHP FPM. This configuration is part of PHP 5.3 and 5.5 available on Ubuntu 12.04 and 14.04.
PHP FPM uses the Fast CGI interface to the web server, and therefore can be used with other web servers, like nginx.
But, we stick to Apache, which has very good performance when it is in MPM Worker, since the threaded server is much more efficient and light weight than the Pre-Fork server.
In the sections below, we describe how to setup and tune Apache2 and PHP FPM optimally for both Ubuntu 12.04 and 14.04, since some sites will stay for some time on the former because of some incompatibilities of some modules with the latter. The former has Apache 2.2, while the latter has Apache 2.4. Because of this and other changes, the locations of the files are different, and some parameters are different too.
We assume a VPS of modest size, 1 or 2 GB of RAM. The values should be adjusted for larger servers of 8GB or more.
Apache MPM Worker Configuration
aptitude install apache2-mpm-worker apache2-threaded-dev apache2-utils libapache2-mod-fastcgi php5-fpm
We then configure Apache MPM Worker. Note that in Ubuntu 12.04, the configuration goes in /etc/apache/conf.d/mpm-worker.conf. As for Ubuntu 14.04, the file should be: /etc/apache2/conf-enabled/mpm-worker.conf.
<IfModule mpm_worker_module>
ServerLimit 300
StartServers 3
MinSpareThreads 3
MaxSpareThreads 10
ThreadsPerChild 10
MaxClients 300
MaxRequestsPerChild 1000
</IfModule>
Then, we enable the required module for FastCGI to work:
sudo a2enmod fastcgi
Ubuntu 12.04 Configuration
On Ubuntu 12.04, it is better to stay with APC, rather than try with Zend OpCache. You can try running with Zend OpCache, but if you get segfaults, then stick with APC.
First, we tell Apache to send requests for files ending with .php to the PHP FPM server. This goes in the file: /etc/apache2/conf.d/php-fpm.conf, as follows:
<IfModule mod_fastcgi.c>
Alias /usr/sbin/php-fpm.fcgi /usr/sbin/php-fpm
AddHandler php-fastcgi .php
Action php-fastcgi /usr/sbin/php-fpm.fcgi
FastCGIExternalServer /usr/sbin/php-fpm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 600
<Directory /usr/sbin>
Options ExecCGI FollowSymLinks
SetHandler fastcgi-script
Order allow,deny
Allow from all
</Directory>
</IfModule>
Then, in the file /etc/php5/fpm/pool.d/www.conf, you should have the following values, so that you do not exceed the available memory for the server:
[www]
user = www-data
group = www-data
chdir = /
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 10
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 2000
And finally we increase the memory for PHP and Zend OpCache from the default, in the file: /etc/php5/fpm/conf.d/local.ini.
For fairly simple sites with a small number of modules and themes (e.g. 100 or less), shm_size of 64MB is sufficient. For sites with a large number of modules (~200 or so), you will need to increase that to 128MB or more. Likewise, the value for memory_limit needs to increase for complex sites as well, perhaps up to 256MB in some cases.
To know exactly how much memory APC is using, you need to copy the apc.php file from /usr/share/doc/php temporarily to web root and access it from a browser.
; You may need to increase the values below, depending on your site's complexity
memory_limit = 96M
apc.shm_size = 64M
Ubuntu 14.04 LTS
For Ubuntu 14.04, you should not use APC, but rather the built Zend OpCache.
First, we tell Apache to send requests for files ending with .php to the PHP FPM server. This goes in the file /etc/apache2/conf-enabled/php-fpm.conf
<IfModule mod_fastcgi.c>
Alias /php-fcgi /usr/lib/cgi-bin/php5
AddHandler php .php
Action php /php-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5 -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 600
<Directory /usr/lib/cgi-bin>
AllowOverride All
Options +ExecCGI +FollowSymLinks
Require all granted
</Directory>
</IfModule>
Then we configure the maximum number of PHP processes that would provide good performance, but not exceed the server's memory. This goes in the file /etc/php5/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
chdir = /
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 10
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 2000
And finally we increase the memory for PHP and Zend OpCache from the default, in the file: /etc/php5/fpm/conf.d/local.ini.
For fairly simple sites with a small number of modules and themes (e.g. 100 or less), memory_consumption of 64MB is sufficient. For sites with a large number of modules (~200 or so), you will need to increase that to 128MB or more. Likewise, the value for memory_limit needs to increase for complex sites as well, perhaps up to 256MB in some cases.
To know exactly how much memory Zend OpCache is using, you need to get the opcache.php script from Rasmus Lerdorf's GitHub, and copy it temporarily to web root and access it from a browser.
; You may need to increase the values below, depending on your site's complexity
memory_limit = 96M
opcache.memory_consumption = 64M
Enabling Required Modules
The final step before restarting the servers is to enable the following Apache modules. This ensures that Apache, PHP-FPM and Drupal work properly together:
sudo a2enmod fastcgi actions rewrite deflate expires
Restarting
Now, restart Apache and PHP, so the above configurations take effect:
sudo service php5-fpm restart
sudo service apache2 restart
Now, you have a very performant yet light weight setup.
Comments
Elioty (not verified)
Benchmarks
Mon, 2014/08/11 - 11:11Hello
Thank you very much for this article. Very well written with the whole process explained to set up this configuration. However, could you do some new and fresh benchmarks like you did in your previous article to compare this new solution against the one you suggested 5 years ago?
I will test it anyway and see how my Symfony2 apps react (under Ubuntu 14.04 with PostgreSQL 9.3).
Thanks in advance.
Elioty
Khalid
Good
Mon, 2014/08/11 - 13:00PostgreSQL is little used in the Drupal universe, but it is good that you will do benchmarks of any kind. Please share them here (at least mod_php vs. PHP-FPM).
I have been using it in production for many sites of all sizes, and it is fast.
My guess is that it will be as good as, if not better than, fcgid, with the added benefit of a shared op code cache, rather than one copy per process.
Popa Adrian (not verified)
Restarting lines
Wed, 2014/09/17 - 07:38Restarting lines should be
Khalid
Thanks ...
Wed, 2014/09/17 - 08:39Thanks, I fixed the typo.
Erobober (not verified)
What about files like
Thu, 2014/11/27 - 17:13What about files like "malware.jpg.php" for Ubuntu 14.04 lts configured in php-fpm.conf? Looks like they come.
Khalid
Not clear
Thu, 2014/11/27 - 19:57Your question is not clear to me.
If you did find such file on your system, you should assume that your site has been compromised.
Carlos Miranda Levy (not verified)
Varnish on top?
Mon, 2014/12/01 - 14:15Thanks for the article, I used the old one as the basis of the deployment guide for our servers for the past few years and I quote it in the optimization section of our Ubuntu for Drupal instructions in Spanish at http://www.socinfo.com/ubuntu/configuracion -
What are your thoughts or experience on deploying Varnish on top of this config?
Mainly following the instructions at:
https://www.digitalocean.com/community/tutorials/how-to-speed-up-your-drupal-7-website-with-varnish-4-on-ubuntu-14-04-and-debian-7
Thanks in advance for any comment or hint.
Alan (not verified)
uploadprogress
Sat, 2014/12/06 - 21:17Thanks for the instruction, works great!
For Drupal 7, One thing is the uploadprogress now seems not able to work after switch.
In the status report page, it says:
"Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php and not as FastCGI."
Do you have a workaround ?
THank you.
Khalid
Issues open for it ...
Sat, 2014/12/06 - 22:41No. I don't have one off hand.
But there are a couple of issues open for it: #1559116 and #1561866.
ed (not verified)
help!
Wed, 2014/12/17 - 06:12Hi
I tried to follow your tutorial on 12.04 but now my system is completely unworkable and i think i am going to have to reinstall the entire system!!
I have tried to remove apache2 and reinstall and remove php-fpm so that I can just be back where i was but i fear that my system is now lost...any advice?
If you follow this tutorial you may have mpm install issues, you probably wont have
/etc/apache/conf.d/mpm-worker.conf
the folder on 12.04 is apache2 but it wont have mpm-worker.conf in it.
Pages