How to Install and Configure PHP on Apache

How to install and configure PHP on Apache

How to install and configure PHP on Apache

PHP and Apache have been running the web together for decades, and it’s still one of the most common stacks I set up for clients, whether it’s a fresh WordPress install or a custom application. In this guide, I’ll walk through installing PHP, connecting it to Apache the modern way, and configuring it properly for production use.

Understanding How PHP Works with Apache

There are two main ways to run PHP alongside Apache:

  1. mod_php – PHP runs as an Apache module, embedded directly in Apache’s worker processes. It’s simple to set up but ties PHP’s performance and stability to Apache’s process model, and only works with the older mpm_prefork module.
  2. PHP-FPM (FastCGI Process Manager) – PHP runs as an independent process pool, and Apache communicates with it via FastCGI (mod_proxy_fcgi). This is the modern, recommended approach: it’s faster, more memory-efficient, and works with Apache’s high-performance mpm_event module.

This guide focuses primarily on PHP-FPM, since it’s the standard for new deployments, with a note on mod_php for completeness.

Prerequisites

Installing PHP-FPM and Connecting It to Apache

Step 1: Install PHP-FPM

Debian/Ubuntu:

sudo apt update
sudo apt install php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip

CentOS/RHEL:

sudo dnf install epel-release
sudo dnf install php-fpm php-mysqlnd php-curl php-gd php-mbstring php-xml php-zip

Check the installed version:

php -v

Step 2: Switch Apache to mpm_event and Enable FastCGI Proxy Modules

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod proxy_fcgi
sudo a2enmod setenvif
sudo a2enconf php8.3-fpm
sudo systemctl restart apache2

(Replace 8.3 with your installed PHP version — check with php -v.)

Step 3: Start and Enable PHP-FPM

sudo systemctl start php8.3-fpm
sudo systemctl enable php8.3-fpm
sudo systemctl status php8.3-fpm

Step 4: Configure the Virtual Host


    ServerName example.com
    DocumentRoot /var/www/example.com/public_html

    
        AllowOverride All
        Require all granted
    

    
        SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/"
    

    ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
    CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined

Enable the site and restart Apache:

sudo a2ensite example.com.conf
sudo apachectl configtest
sudo systemctl restart apache2

Step 5: Test PHP Is Working

sudo nano /var/www/example.com/public_html/info.php

Visit http://example.com/info.php in a browser. You should see the PHP configuration page. Delete this file after testing — it exposes detailed server information that shouldn’t be public.

sudo rm /var/www/example.com/public_html/info.php

Alternative: Installing mod_php (Legacy Approach)

If you have a specific reason to use mod_php (some legacy applications assume it), here’s the setup:

sudo apt install libapache2-mod-php
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo a2enmod php8.3
sudo systemctl restart apache2

Note that mod_php requires mpm_prefork, which handles one request per process/thread and generally performs worse under high concurrency than mpm_event with PHP-FPM.

Configuring php.ini for Production

Locate your php.ini file:

php --ini

For FPM, it’s typically at /etc/php/8.3/fpm/php.ini. Key production settings to review:

; Hide PHP version from response headers (security)
expose_php = Off

; Disable dangerous functions if not needed
disable_functions = exec,passthru,shell_exec,system,proc_open,popen

; Limit file upload size appropriately
upload_max_filesize = 20M
post_max_size = 20M

; Set a reasonable execution time limit
max_execution_time = 30

; Enable OPcache for performance
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60

; Error handling - never display errors in production
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log

After editing, restart PHP-FPM:

sudo systemctl restart php8.3-fpm

Tuning PHP-FPM Process Management

Edit the pool configuration, typically at /etc/php/8.3/fpm/pool.d/www.conf:

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

Restart after changes:

sudo systemctl restart php8.3-fpm

Real-World Use Cases

Common Mistakes to Avoid

  1. Leaving phpinfo() accessible in production – This exposes internal paths, loaded modules, and configuration details useful to attackers.
  2. Using mod_php with mpm_event – This combination doesn’t work; mod_php requires mpm_prefork.
  3. Not matching the socket path in Apache config to the actual PHP-FPM socket – A common cause of 502 errors after a PHP version upgrade.
  4. Ignoring pm.max_children tuning – Leaving it at low defaults on a high-traffic site causes requests to queue and time out.
  5. Displaying errors in productiondisplay_errors = On leaks file paths and code structure to visitors; always log errors instead.

Security Best Practices

Performance Optimization Tips

Troubleshooting

502 Bad Gateway:

White screen with no error message:

“File not found” errors for .php files:

High memory usage:

Frequently Asked Questions

Should I use PHP-FPM or mod_php for a new project? PHP-FPM, in almost all cases. It’s faster, more memory-efficient, and compatible with Apache’s modern mpm_event MPM.

How do I run multiple PHP versions on the same server? Install multiple PHP-FPM versions side by side (e.g., php8.1-fpm and php8.3-fpm), each with its own socket, and point different virtual hosts to the appropriate socket in their FilesMatch block.

Do I need to restart Apache after changing php.ini? No — restart PHP-FPM instead (sudo systemctl restart php8.3-fpm), since PHP-FPM manages its own processes independently of Apache.

Is PHP still relevant in 2026? Yes. PHP continues to power a substantial share of the web, particularly through WordPress and other CMS platforms, and modern PHP (8.x) with OPcache and PHP-FPM is a solid, performant choice.

Summary and Key Takeaways

References

Exit mobile version