How to Configure Apache and PHP for High Traffic Websites on Linux Server

Spread the love

Almost every tutorial on how to install the LAMP stack (Linux, Apache, MySQL, PHP) will recommend that you use the built-in Apache module for processing PHP scripts. For example, in Ubuntu you would enable this when you use a command such as sudo apt install libapache2-mod-phpto install a package. This would in turn force Apache to use mpm_prefork. Every time a visitor accesses your website, a new process will be launched to handle that connection. This works well when traffic is low.

But, it becomes a huge issue if you get a sudden burst of traffic. For example, a Reddit post may include your website, and if the post gets popular, you may get thousands of visitors in just a few minutes.

In a best case scenario, if Apache is able to handle the traffic burst, some unlucky visitors may have to wait perhaps thirty to sixty seconds until the page is loaded, which is absurd in today’s world. In a worst case scenario, the server will start to lag badly, and some connections will be simply dropped because of lack of resources. In this case visitors will see an error in their browsers.

It’s not a good scenario either way, since you potentially lost the attention of hundreds or thousands of interested readers, customers or fans.

Unfortunately, PHP is a pretty big resource hog either way. But, with mpm_event, Apache can handle sudden bursts of traffic in a much more efficient way. It’s recommended, though, that your server have at least 2GB of RAM and 2 CPU cores, real or virtual, and even more if you expect to have intense traffic spikes, such as more than ten visitors per second. If you’re using a virtual private server, add more virtual CPU cores to your situation and SSD storage. RAM is secondary.

Also read: Nginx vs Apache: Which Serves You Best?

How to Use Apache MPM Event and PHP-FPM on Debian-Based Distributions

On Debian, Ubuntu or other distros from this family simply avoid installing the “libapache2-mod-php” package. When you install Apache it uses MPM event by default. But upon installing the mentioned package, a script disables MPM event and enables MPM prefork. The Apache PHP module can only work (safely) with mpm_prefork. Of course, without “libapache2-mod-php,” you have no processor for PHP files. So you will use PHP-FPM instead of the PHP module included in Apache. Here is how you would install a LAMP stack on a fresh server. You can adapt the steps according to your web application’s requirements.

First, log in as root. Then, install Apache.

apt update && apt install apache2

At this point you can see that Apache does indeed ship with MPM event enabled by default.

apachectl -V

Install PHP-FPM.

apt install php-fpm

You will see instructions on how to enable the PHP processor in Apache.

Enable FastCGI protocol.

a2enmod proxy_fcgi

Enable PHP-FPM default configuration for Apache.

a2enconf php7.0-fpm

Note: in future versions of Debian/Ubuntu, this command could change to something else, e.g. a2enconf php7.6-fpm, because PHP-FPM would be a different version.

Restart Apache.

systemctl restart apache2

Install the rest of your requirements for your PHP application. Here’s an example:

apt install mariadb-server php-mysql

This would install a database server and the PHP MySQL module so that your PHP application can connect to a database.

Also read: How to Protect Against DDoS with Mod_evasive on Apache Server

How to Use Apache MPM Event and PHP-FPM on RedHat-Based Distributions

The other popular server distribution choice is RedHat, or CentOS. In the same way as above, an example of a clean install of Apache with MPM event enabled and PHP-FPM will be offered.

Log in as root and install Apache.

yum install httpd

Unlike Debian-based distros, here you will see that Apache uses MPM prefork by default, at least on the latest CentOS 7 available at the time of writing.

apachectl -V

To enable MPM event, you have to edit a configuration file.

sed -i '/mpm_prefork\.so$/s/^/#/' /etc/httpd/conf.modules.d/00-mpm.conf

This will add a # sign to comment (inactivate) the line LoadModule mpm_prefork_module modules/mod_mpm_prefork.so.

Now uncomment (activate) the line #LoadModule mpm_event_module modules/mod_mpm_event.so by removing the preceding # sign with the next command.

sed -i '/mpm_event\.so$/s/^#//' /etc/httpd/conf.modules.d/00-mpm.conf

Start Apache and enable it to autostart at boot.

systemctl start httpd.service
systemctl enable httpd.service

Check if Apache now uses MPM event.

apachectl -V

Install PHP-FPM and FastCGI module.

yum install php-fpm mod_fcgid

Create “/etc/httpd/conf.d/php.conf” to instruct Apache on how to process PHP files. Copy ALL content below, and paste it all at once in the terminal, then press ENTER.

cat <<PASTE > /etc/httpd/conf.d/php.conf
# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
<IfModule proxy_fcgi_module>
# Enable http authorization headers
<IfModule setenvif_module>
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
 
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
#SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
<FilesMatch ".+\.phps$">
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
Require all denied
</FilesMatch>
</IfModule>
</IfModule>
PASTE

The credit for this great config goes to Debian. Other sources recommend a simple configuration file such as:

<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

But this is vulnerable to some attacks, and if certain services fail, you may expose PHP files to the public, in turn potentially exposing stored passwords, code and sensitive data.

Restart Apache.

systemctl restart httpd.service

Start PHP-FPM and enable its autostart at boot.

systemctl start php-fpm.service
systemctl enable php-fpm.service

Conclusion

You now have an Apache server that scales much better with traffic. However, remember that you’re using the default settings, as in what’s “best” for most people. If you really want to get the most out of your HTTP server, you have to read about various variables you can tune. The right values for these are highly dependent on your server’s resources, expected traffic and PHP application.

Subscribe to our newsletter!

Our latest tutorials delivered straight to your inbox

Sign up for all newsletters.
By signing up, you agree to our Privacy Policy and European users agree to the data transfer policy. We will not share your data and you can unsubscribe at any time. Subscribe


Alexandru Andrei

Fell in love with computers when he was four years old. 27 years later, the passion is still burning, fueling constant learning. Spends most of his time in terminal windows and SSH sessions, managing Linux desktops and servers.

Comments are closed